Regular polygon
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1808 Accepted Submission(s): 709
Problem Description
On a two-dimensional plane, give you n integer points. Your task is to figure out how many different regular polygon these points can make.
Input
The input file consists of several test cases. Each case the first line is a numbers N (N <= 500). The next N lines ,each line contain two number Xi and Yi(-100 <= xi,yi <= 100), means the points’ position.(the data assures no two points share the same position.)
Output
For each case, output a number means how many different regular polygon these points can make.
Sample Input
4 0 0 0 1 1 0 1 1 6 0 0 0 1 1 0 1 1 2 0 2 1
Sample Output
1
2
本身是一道水题,但做这种水题我脑子很容易一下抽,WA了10几次
题意:
给你n个点,求出这n个点能组成多少个不同的正多边形
解析:
因为坐标都是整数,而在边数>=4的多边形中肯定至少存在一条斜的边,所以这样点的坐标一定不是整数了,因此该正多边形一定是正方形。(详细证明网上好像说某个国家队的大神写过一篇论文证明过)
接下来就是暴力枚举,先选定两个点,再根据这两个点算出可以组成正方形的另外两个点,再判定另外两个点是否存在即可
当时WA了这么多次的原因是判定条件写错了。找正方形的时候其实有两种情况一种是斜向右下的边,此时另外两个点又有两种情况是一种是x+,y+(在边的上方),另一种是x-,y-(在边的下方),还有一种是斜向左下的边此时两种情况是1.x-,y+(在边的上方) 2.x+,y-(在边的下方)
就是这两情况判定条件是横坐标之差的+-以及纵坐标之差的+-
但我的判定条件竟然是前一种不满足的话就后一种,这样肯定会有边是后一种情况不满足的,但在一开始在前一种情况计算中满足了情况,这样就多加了
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 3000
using namespace std;
typedef struct Point
{
int x,y;
}Point;
Point loca[MAXN];
int map[MAXN][MAXN];
int cmp(Point a,Point b)
{
if(a.y==b.y)
return a.x<b.x;
return a.y<b.y;
}
bool judge(Point a,Point b)
{
if(a.x>=0&&b.x>=0&&a.y>=0&&b.y>=0&&map[a.x][a.y]==1&&map[b.x][b.y]==1)
{
return true;
}
return false;
}
int main()
{
int n,ans;
while(scanf("%d",&n)!=EOF)
{
ans=0;
memset(map,0,sizeof(map));
for(int i=0;i<n;i++)
{
scanf("%d%d",&loca[i].x,&loca[i].y);
loca[i].x+=100;
loca[i].y+=100;
map[loca[i].x][loca[i].y]=1;
}
sort(loca,loca+n,cmp);
for(int i=0;i<n;i++)
{
for(int j=i+1;j<n;j++)
{
int xx=loca[i].x-loca[j].x;
int yy=loca[i].y-loca[j].y;
Point a,b,c,d;
if(xx>=0&&yy<=0)
{
xx=abs(xx);
yy=abs(yy);
a.x=loca[i].x+yy;
a.y=loca[i].y+xx;
b.x=loca[j].x+yy;
b.y=loca[j].y+xx;
if(judge(a,b))
{
ans++;
// flag=1;
}
c.x=loca[i].x-yy;
c.y=loca[i].y-xx;
d.x=loca[j].x-yy;
d.y=loca[j].y-xx;
if(judge(c,d))
{
ans++;
//flag=1;
}
}
else
{
xx=abs(xx);
yy=abs(yy);
a.x=loca[i].x-yy;
a.y=loca[i].y+xx;
b.x=loca[j].x-yy;
b.y=loca[j].y+xx;
if(judge(a,b))
{
ans++;
//flag=1;
}
c.x=loca[i].x+yy;
c.y=loca[i].y-xx;
d.x=loca[j].x+yy;
d.y=loca[j].y-xx;
if(judge(c,d))
{
ans++;
//flag=1;
}
}
}
}
//printf("%d\n",ans);
printf("%d\n",ans/4);
}
return 0;
}
在网上看了代码后发现其实并不用那么麻烦来分情况。。。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 3000
using namespace std;
typedef struct Point
{
int x,y;
}Point;
Point loca[MAXN];
int map[MAXN][MAXN];
//int rowloca[300];
int cmp(Point a,Point b)
{
if(a.y==b.y)
return a.x<b.x;
return a.y<b.y;
}
bool judge(Point a,Point b)
{
if(a.x>=0&&b.x>=0&&a.y>=0&&b.y>=0&&map[a.x][a.y]==1&&map[b.x][b.y]==1)
{
return true;
}
return false;
}
int main()
{
int n,ans;
while(scanf("%d",&n)!=EOF)
{
ans=0;
memset(map,0,sizeof(map));
for(int i=0;i<n;i++)
{
scanf("%d%d",&loca[i].x,&loca[i].y);
loca[i].x+=100;
loca[i].y+=100;
map[loca[i].x][loca[i].y]=1;
}
sort(loca,loca+n,cmp);
for(int i=0;i<n;i++)
{
for(int j=i+1;j<n;j++)
{
Point a,b;
int xx=loca[i].x-loca[j].x;
int yy=loca[i].y-loca[j].y;
a.x=loca[i].x-yy;
a.y=loca[i].y+xx;
b.x=loca[j].x-yy;
b.y=loca[j].y+xx;
if(judge(a,b))
{
ans++;
}
Point c,d;
c.x=loca[i].x+yy;
c.y=loca[i].y-xx;
d.x=loca[j].x+yy;
d.y=loca[j].y-xx;
if(judge(c,d))
{
ans++;
}
}
}
printf("%d\n",ans/4);
}
return 0;
}