UVA1595(Symmetry)(Water Preblem)

UVA1595传送门
思路:枚举同一行的每两个点的中点横坐标,然后看全部“对称”点的中点横坐标是否相同,是输出YES,否输出NO。那如何枚举每两个"对称"点呢?很简单,先对每一行根据横坐标排序,然后每一行两端的点即相对中间对称必定是对称点!如果算出来不是对称点则证明此题没有一个纵列使其对称,至于如何证明大家可以根据样例演算一下。
AC代码(10ms)

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <iterator>

using namespace std;
vector<int> a[20010];

int main()
{
    int t;
    scanf("%d",&t);
    while(t--){
        int n,x,y;
        double l;
        bool flag = true,stand = true;
        vector<int>::iterator it_b,it_e;
        scanf("%d",&n);
        for(int i = 0;i<n;i++){
            scanf("%d%d",&x,&y);
            a[y+10000].push_back(x);//防止输入的y超限,若y = -10000则刚好为数组a的0
        }
        for(int i = 0;i<20010;i++){     //枚举每一行
            if(!a[i].empty()){
                double curl;
                int cnt = ((int)a[i].size()+1)/2;  //确定对称点对的个数
                sort(a[i].begin(),a[i].end());    //为vector数组a排序
                it_b = a[i].begin();                  //从两端开始搜索
                it_e = a[i].end();
                it_e--;                                    //a[i].end()并不是最后一个元素的指针
                while(true){
                    curl = ((double)*it_b+(double)*it_e)/2;
                    if(flag)    flag = false,l = curl;    //确定第一个对称点对的中点点横坐标
                    else{
                        if(curl!=l){                            //不满足对称条件,标记退出
                            stand = false;
                            break;
                        }
                    }
                    if(--cnt<=0) break;
                    it_b++,it_e--;
                }
                if(!stand)  break;
            }
        }
        if(stand)  printf("YES\n");
        else       printf("NO\n");
        for(int i = 0;i<20010;i++)
            if(!a[i].empty())                          //清空vector数组!不然对下一次运算会有影响
                a[i].clear();
    }
    return 0;
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容