题意:问n个点中是否存在两对不同的点的曼哈顿距离相等。
题解:有的同学可能会想,直接算出每两个点之间的曼哈顿距离,然后看看有没有重复的就可以了,不过这个题上给的n是 1e5
那样算的话一定超时,那么应该怎么办呢,想一下,这个题上还给了一个 m,m最多是1e5,所以曼哈多距离最多是2*1e5,
根据鸽巢原理,只要我们算的点超过了2*m(m是题上说的m),就一定有距离相等的。所以判断的时候我们可以用两种方式,一边判断有没有重复的点,一边判断计算的点有没有超过2*m,最多算2e5次就结束了,所以肯定不会超时的,
代码:
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<math.h>
using namespace std;
#define met(Q,QQ) memset(Q,QQ,sizeof(Q))
const int maxn=1e5+7;
struct stu
{
int x;
int y;
}A[maxn];//存点的坐标
int b[2*maxn];//起到标记作用,判断这个点有没有出现过,
int main()
{
int t,n,m;
scanf("%d",&t);
while(t--)
{
met(b,0);
met(A,0);
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d %d",&A[i].x,&A[i].y);
int cnt=0;
int AA=0;
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
cnt++;//记录计算了几个点,
if(cnt>(2*m)) //鸽巢定理
{
AA=1;
break;
}
int sum=abs(A[i].x-A[j].x)+abs(A[i].y-A[j].y);
if(b[sum]==0)
{
b[sum]++;
}
else
{
AA=1;
break;
}
}
if(AA==1) break;
}
if(AA) printf("YES\n");
else printf("NO\n");
}
return 0;
}