题意:D和d在一个有n个点的二维平面上移动一颗石头,D先移动,规则为,当石头在点x,且上一次移动距离为d,移动到下点y,满足distance(x,y)>d,且y未访问过,直到一方不能移动则输,若D和d都使用最好的策略,那么当D赢,输出YES,否则输出NO。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct Point{
int x,y;
};
struct Edge{
ll dis;//距离
int a,b;
bool operator<(const Edge &rhs)const{
return dis>rhs.dis;
}
};
int main(){
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
int tcase;
cin>>tcase;
while(tcase--){
int n;
cin>>n;
vector<Point>P(n+1);//定义一个n+1大小的向量
//输入点
for(int i=1;i<=n;i++){
cin>>P[i].x>>P[i].y;
}
vector<Edge>E;
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
auto get_dis = [&](int x1,int y1,int x2,int y2)->ll{
return 1LL*(x1-x2)*(x1-x2)+1LL*(y1-y2)*(y1-y2);
};//两点间的距离的平方
E.push_back({get_dis(P[i].x,P[i].y,P[j].x,P[j].y),i,j});
}
}
sort(E.begin(),E.end());
vector<int>del(n+1);
int m = (int)E.size();
vector<int>t;
ll td =-1;
for(int i=0;i<m;i++){
if(del[E[i].a]||del[E[i].b])continue;
if(td==-1&&td==E[i].dis){
t.push_back(E[i].a);
t.push_back(E[i].b);
td = E[i].dis;
}
else{
for(auto e:t)del[e] = 1;
if(del[E[i].a]||del[E[i].b]){
td = -1;
t.clear();
continue;
}
td = E[i].dis;
t = {E[i].a,E[i].b};
}
}
if(td!=-1){
for(auto e:t) del[e] = 1;
}
vector<int> ans;
for(int i= 1;i<=n;i++){
if(!del[i]) ans.push_back(i);
}
assert((int)ans.size()<=1);
if(ans.empty()){
cout<<"YES"<<endl;
}
else if(ans[0]!=1){
cout<<"YES"<<endl;
}
else{
cout<<"NO"<<endl;
}
}
return 0;
}