题目大意:
已知有一系列的点的(x,y),问我们能不能找出一个x=a的直线使得所有点关于这条线对称。
各位大佬都说是水题,555.
但是我觉得这道题让我对stl中的map有了更深的理解,以及让我对这种问题思考多了一些角度。
首先,我们应该意识到有几个变量是这个问题的关键突破,点的横坐标,点的纵坐标,和点到这条对称轴的距离。
首先我们看点的纵坐标,假如点需要对称,那么我们是不是应该统计出所有纵坐标相等的点呢?这是一个很大的突破口。
第二个重要的观察在于,假如有一条对称轴满足某个纵坐标族的要求,即:对于一系列的纵坐标相等的点,我们找到的分界线的对称轴,那么这条对称轴必须对其它纵坐标族也同时有效
关于得到纵坐标族 点对的 对称轴,我们可以这样,首先得到纵坐标相同的点然后把它们的横坐标拿下来从小到大排序,然后建立头指针和尾指针,每次计算头尾指针对应的坐标轴。头指针++和尾指针--
所以,题目的思路就是:
建立map<int,vector<int>> 其中key是纵坐标,后面的vector push进去一系列的对应横坐标。
求对称轴,完事。
总结:
我们可以用map得到我们需要统计的某种特定属性的元素的集合。
AC代码:
#include <bits/stdc++.h>
using namespace std;
int main(){
int cases;
cin>>cases;
for(int i=0;i<cases;i++){
int poino;
cin>>poino;
map<int,vector<int>> mp;
for(int j=0;j<poino;j++){
int x,y;
cin>>x>>y;
mp[y].push_back(x);
}
int suc_flag = 1;
int co =0;
double sym_line = -1;
for(auto &poi:mp){
int sz= poi.second.size();
sort(poi.second.begin(),poi.second.end(),less<int>());
if(!co){
if(sz % 2==0){
sym_line = (poi.second[sz/2-1] + poi.second[sz/2+1-1])/2;
}else sym_line = poi.second[(sz+1)/2-1];
co = 1;
}
int move = 0;
if(sz%2 ==0)move = sz/2;
else move = (sz+1)/2;
int fir = 0;
int las = sz - 1;
for(int mo =0;mo<move;mo++){
if((poi.second[fir]+poi.second[las] )/2 != sym_line){
suc_flag = 0;
break;
}
fir++;
las--;
}
if(!suc_flag)break;
}
if(suc_flag)cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}