poj 2002 Squares ----二分
2012-03-22 12:33 java环境变量 阅读(228) 评论(0) 编辑 收藏 举报
Squares
Time Limit: 3500MS | Memory Limit: 65536K | |
Total Submissions: 11185 | Accepted: 4068 |
Description
A square is a 4-sided polygon whose sides have equal length and adjacent sides form 90-degree angles. It is also a polygon such that rotating about its centre by 90 degrees gives the same polygon. It is not the only polygon with the latter property, however,
as a regular octagon also has this property.
So we all know what a square looks like, but can we find all possible squares that can be formed from a set of stars in a night sky? To make the problem easier, we will assume that the night sky is a 2-dimensional plane, and each star is specified by its x and y coordinates.
So we all know what a square looks like, but can we find all possible squares that can be formed from a set of stars in a night sky? To make the problem easier, we will assume that the night sky is a 2-dimensional plane, and each star is specified by its x and y coordinates.
Input
The input consists of a number of test cases. Each test case starts with the integer n (1 <= n <= 1000) indicating the number of points to follow. Each of the next n lines specify the x and y coordinates (two integers) of each point. You may assume that the
points are distinct and the magnitudes of the coordinates are less than 20000. The input is terminated when n = 0.
Output
For each test case, print on a line the number of squares one can form from the given stars.
Sample Input
4 1 0 0 1 1 1 0 0 9 0 0 1 0 2 0 0 2 1 2 2 2 0 1 1 1 2 1 4 -2 5 3 7 0 0 5 2 0
Sample Output
1 6 1
题目大意:输入n个点的坐标,最多能组成多少个正方形。
思路: 感觉这题思路不难 ,并且是放在二分专题 ,直接用二分考虑的。 我每次枚举两点作为对角线,查找 两外两个点是否存在。 最后结果除 二。
ps:这道题 我提交后跑了1235MS。 - - 。看到其他人交的 对于算法的优化一直不懂,时间复杂度什么的。 我试着优化代码, 还是 1219 MS,没效果。。 问题在代码中 , 请教请教。
第一次交的代码:
//Memory: 172K Time: 1235MS //Language: C++ Result: Accepted #include<stdio.h> #include<stdlib.h> struct point { int x,y; }p[1005]; int cmp(const void * a,const void *b) { struct point * aa=(struct point *)a; struct point * bb=(struct point *)b; if(aa->x==bb->x) return aa->y - bb->y; return aa->x - bb->x; } int b_search(int a,int b,int len) //二分找点(a,b) { int max=len-1,min=0,mid; while(min<=max) { mid=(min+max)/2; if(p[mid].x==a&&p[mid].y==b) return 1; else if(p[mid].x>a|| ( p[mid].x==a&&p[mid].y>b) ) max=mid-1; else min=mid+1; } return 0; } int main() { //freopen("1.txt","r",stdin); int n,i,j,sum; while(scanf("%d",&n)!=EOF&&n) { sum=0; for(i=0;i<n;i++) scanf("%d%d",&p[i].x,&p[i].y); qsort(p,n,sizeof(p[0]),cmp); //排序 优先按x排,再按y排 for(i=0;i<n-1;i++) { for(j=i+1;j<n;j++) { int gx1=p[i].x+p[i].y+p[j].x-p[j].y, gy1=p[i].y+p[j].y+p[j].x-p[i].x, gx2=p[i].x+p[j].x+p[j].y-p[i].y, gy2=p[i].x+p[i].y+p[j].y-p[j].x; if(gx1%2||gx2%2||gy1%2||gy2%2) continue; //结果只可能是整数,应为表达式中得除以二,所以分子如果是奇数全部过滤掉。 else gx1/=2,gy1/=2,gx2/=2,gy2/=2; //求对角线另外两点 (gx1,gy1),(gx2,gy2) if(b_search(gx1,gy1,n) && b_search(gx2,gy2,n)) //二分查找两点是否存在。 sum++; } } printf("%d\n",sum/2); } return 0; }
下面是修改后的代码:
//Memory: 172K Time: 1219MS //Language: C++ Result: Accepted #include<stdio.h> #include<stdlib.h> struct point { int x,y; }p[1005]; int cmp(const void * a,const void *b) { struct point * aa=(struct point *)a; struct point * bb=(struct point *)b; if(aa->x==bb->x) return aa->y - bb->y; return aa->x - bb->x; } int b_search(int a,int b,int len) { int max=len-1,min=0,mid; while(min<=max) { mid=(min+max)/2; if(p[mid].x==a&&p[mid].y==b) return 1; else if(p[mid].x>a|| ( p[mid].x==a&&p[mid].y>b) ) max=mid-1; else min=mid+1; } return 0; } int main() { //freopen("1.txt","r",stdin); int n,i,j,sum; while(scanf("%d",&n)!=EOF&&n) { sum=0; for(i=0;i<n;i++) scanf("%d%d",&p[i].x,&p[i].y); qsort(p,n,sizeof(p[0]),cmp); for(i=0;i<n-1;i++) { for(j=i+1;j<n;j++) { int gx1=p[i].x+p[i].y+p[j].x-p[j].y; // 修改成每一步判断。。但没效果。 if(gx1%2) continue; int gy1=p[i].y+p[j].y+p[j].x-p[i].x; if(gy1%2) continue; int gx2=p[i].x+p[j].x+p[j].y-p[i].y; if(gx2%2) continue; int gy2=p[i].x+p[i].y+p[j].y-p[j].x; if(gy2%2) continue; gx1/=2,gy1/=2,gx2/=2,gy2/=2; if(!b_search(gx1,gy1,n)) continue; //这里也是。假如 a&&b 判断的时候 如果a已经为假了 还会不会运算 b? if(!b_search(gx2,gy2,n)) continue; sum++; } } printf("%d\n",sum/2); } return 0; }