Teacher BoBo is a geography teacher in the school.One day in his class,he marked NN points in the map,the ii-th point is at (Xi,Yi)(Xi,Yi).He wonders,whether there is a tetrad (A,B,C,D)(A<B,C<D,A≠CorB≠D)(A,B,C,D)(A<B,C<D,A≠CorB≠D) such that the manhattan distance between A and B is equal to the manhattan distance between C and D.
If there exists such tetrad,print “YES”,else print “NO”.
Input
First line, an integer TT. There are TT test cases.(T≤50)(T≤50)
In each test case,the first line contains two intergers, N, M, means the number of points and the range of the coordinates.(N,M≤105)(N,M≤105).
Next N lines, the ii-th line shows the coordinate of the ii-th point.(Xi,Yi)(0≤Xi,Yi≤M)(Xi,Yi)(0≤Xi,Yi≤M).
Output
TT lines, each line is “YES” or “NO”.
Sample Input
2
3 10
1 1
2 2
3 3
4 10
8 8
2 3
3 3
4 4
Sample Output
YES
NO
这道题实际上直接去暴力去做就可以了,但是很多人绝对仍为暴力是过不了的,然后一直迟迟没有动手,实际上写的形式的确很向
O(N2)
,但是我后来分析来一下,实际上复杂度只会到
O(M)
,我的做法就是设置一个布尔数组
dis[d]
Z,含义是d这种长度的路径是否出现过,只要出现过就为true,如果再次出现那答案为YES
换言之,当 (N2−N)>4∗M ,答案必为YES
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
bool dis[200005];
struct point
{
int x,y;
}p[100005];
int getDis(point p1,point p2)
{
return abs(p1.x-p2.x)+abs(p1.y-p2.y);
}
int main()
{
int t;
int n,m;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
bool sign=false;
memset(dis,false,sizeof(dis));
for(int i=0;i<n;i++)//时间复杂度不是对这个两层for循环分析,而是dis这个数组的长度
{
scanf("%d%d",&p[i].x,&p[i].y);
if(!sign)
{
for(int j=0;j<i;j++)
{
int d=getDis(p[i],p[j]);
if(dis[d])
{
sign=true;
break;
}
else
dis[d]=true;
}
}
}
if(sign)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}