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;
}
网友评论