波老师(teacher/1S/64M)
【题目描述】
波波老师是一个地理老师。有一天他上课的时候,他在地图上标记了N个点,第i个点在点(Xi,Yi)。他想知道,是否存在四个点(A,B,C,D)(A<B,C<D,A≠C或者B≠D),使AB之间的曼哈顿距离和CD之间的曼哈顿距离相等。
d(i,j)=|X1-X2|+|Y1-Y2|.
如果存在这样的四个点,输出YES,否则输出NO。
【输入格式】
输入文件第一行是一个T(T≤50),表示有T组数据。
接下来有T组数据,每组数据第一行是两个整数N,M(n<=100000,m<=1000000),表示点的个数以及点的坐标的边界,然后有N行,第i行有两个整数Xi,Yi表示第i个点的坐标(Xi,Yi)(0≤Xi,Yi≤M)
【输出格式】
输出文件有T行,每一行为YES或者NO。
【输入】
2
3 10
1 1
2 2
3 3
4 10
8 8
2 3
3 3
4 4
【输出】
YES
NO
【解题思路】
在做这一题时,不要被n的大小给欺骗了。其实,只要暴力就能过了。为什么呢?
因为它有m的限制,所以两点之间可能最大的曼哈顿距离是2m。然后根据鸽巢原理,暴力枚举的最大次数是min(n^2,2m),所以,暴力是可行的。
【程序】
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
struct Point{
int x,y;
};
Point a[100010];
int f[1000010];
int t,n,m;
bool bo;
int main()
{
freopen("teacher.in","r",stdin);
freopen("teacher.out","w",stdout);
scanf("%d",&t);
for(int tt=1;tt<=t;tt++)
{
memset(a,0,sizeof(a));
memset(f,0,sizeof(f));
bo = false;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&a[i].x,&a[i].y);
}
for(int i=1;i<n && (!bo);i++)
for(int j=i+1;j<=n;j++)
{
int d = abs(a[i].x - a[j].x) + abs(a[i].y - a[j].y);
if(f[d])
{
printf("YES\n");
bo = true;
break;
}
f[d] = 1;
}
if(!bo) printf("NO\n");
}
return 0;
}