POJ 2002 Squares
给出N个点,判断可以组成多少个正方形。最后输出正方形的个数。
思路:枚举每两个点,计算出另外的两个点,若另外两点存在则正方形存在。
这样得到的结果是最终结果的二倍,因为每一个正方形均累加了两次。
另外两点的计算方法:
设AC和BD的交点O的坐标为(X0,Y0),
则有 X0 = (X1+X3)/2 , Y 0 = (Y1+Y3)/2;
从图上可以看出:
X2-X0 = Y3-Y0, Y2-Y0 = X0-X3;
将上述四式合并得:
X2 = (X1+X3+Y3-Y1)/2;
Y2 = (Y1+Y3+X1-X3)/2;
同理可得:
X4 = (X1+X3-Y3+Y1)/2;
Y4 = (Y1+Y3-X1+X3)/2;
1 #include <iostream> 2 #include <cstdlib> 3 #include <cstdio> 4 #include <cmath> 5 #include <cstring> 6 #include <algorithm> 7 8 using namespace std; 9 10 struct P 11 { 12 int x,y; 13 }point[1010]; 14 15 bool cmp(P p1,P p2) 16 { 17 if(p1.x == p2.x) 18 return p1.y < p2.y; 19 return p1.x < p2.x; 20 } 21 22 bool check(P p,int n) 23 { 24 int first = 0,mid,last = n-1; 25 p.x >>= 1; 26 p.y >>= 1; 27 while(1) 28 { 29 mid = (first+last)/2; 30 if(point[mid].x == p.x && point[mid].y == p.y) 31 return true; 32 if(point[mid].x < p.x || (point[mid].x == p.x && point[mid].y < p.y)) 33 { 34 first = mid+1; 35 } 36 else 37 { 38 last = mid-1; 39 } 40 if(last < first) 41 return false; 42 } 43 } 44 45 int main() 46 { 47 int ans; 48 int n,i,j; 49 P t1,t2,p1,p2; 50 while(scanf("%d",&n) && n) 51 { 52 ans = 0; 53 for(i = 0;i < n; i++) 54 scanf("%d %d",&point[i].x,&point[i].y); 55 sort(point,point+n,cmp); 56 57 for(i = 0;i < n; i++) 58 { 59 for(j = i+1;j < n; j++) 60 { 61 p1 = point[i]; 62 p2 = point[j]; 63 t1.x = point[i].x+point[j].x+point[j].y-point[i].y; 64 t1.y = point[i].y+point[j].y+point[i].x-point[j].x; 65 t2.x = point[i].x+point[j].x-point[j].y+point[i].y; 66 t2.y = point[i].y+point[j].y+point[j].x-point[i].x; 67 if((t1.x&1) == 0 && (t1.y&1) == 0 && (t2.x&1) == 0 && (t2.y&1) == 0 && check(t1,n) && check(t2,n)) 68 { 69 ++ans; 70 } 71 } 72 } 73 printf("%d\n",(ans>>1)); 74 } 75 return 0; 76 }