poj 2002 Squares ----二分
2012-03-22 12:33 java环境变量 阅读(232) 评论(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;
}
浙公网安备 33010602011771号