題意:問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;
}