题目:传送门。
题意:平面上有n个点,问是否存在四个点 (A,B,C,D)(A<B,C<D,A≠CorB≠D)使得AB的横纵坐标差的绝对值的和等于CD的横纵坐标差的绝对值的和,n<10^5,点的坐标值m<10^5。
题解:表面上这道题复杂度是O(n^2)会超时的,而实际上这些坐标差绝对值的和最大是2*10^5,所以复杂度不是O(n^2),而是O(min(n^2,m)),这就是著名的鸽笼原理。
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> using namespace std; int abs(int i) { if(i<0) return -i; return i; } int cal(int x,int y,int x1,int y1){ return abs(x-x1) + abs(y-y1); } int main() { int n,m,T,x[100005],y[100005]; bool a[200005]; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); memset(a,0,sizeof(a)); for(int i=0;i<n;i++) { scanf("%d%d",&x[i],&y[i]); } for(int i=0;i<n;i++) for(int j=i+1;j<n;j++) { int t=cal(x[i],y[i],x[j],y[j]); if(a[t]) { puts("YES"); goto NEXT; } a[t]=true; } puts("NO"); NEXT:; } return 0; }