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
題意:
給你一些整數點,判斷這些整數點能否構成不同的正多邊形。
想法:
1.只有正方形才能分解成等腰直角三角形能用整數點表示,所以題目就是找正方形個數。具體證明整數點只能存在正方形參考楊景欽在2017國家集訓隊的論文。
2.直接用四個點六條邊來判斷邊是否相等,對角邊是否滿足勾股定理會超時。
3.綜上我們選擇兩個點來求出能構成正方形的另外兩個點的座標,判斷這兩個點的座標是否已經給出,,如圖:
tips:
1.選擇的兩個點是一條直角邊上的點,不是對角邊的頂點。
2.兩個點能同時在左邊和右邊分別構成正方形,所以要判斷兩次。
3.因爲座標可能爲負,標記時用的數組,所以要+300以上。
4.兩個點能做四次直角邊,所以最後答案要除以4。
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int vis[1500][1500];
struct point
{
int x,y;
} p[1500];
int main()
{
int n;
while(~scanf("%d",&n))
{
int ans=0;
memset(vis,0,sizeof vis);
for(int i=0; i<n; ++i)
{
scanf("%d%d",&p[i].x,&p[i].y);
p[i].x+=300;
p[i].y+=300;
vis[p[i].x][p[i].y]=1;
}
for(int i=0; i<n; ++i)
{
for(int j=i+1; j<n; ++j)
{
int disx=p[j].x-p[i].x;
int disy=p[j].y-p[i].y;
if(vis[p[i].x+disy][p[i].y-disx]&&vis[p[j].x+disy][p[j].y-disx])
ans++;
if(vis[p[i].x-disy][p[i].y+disx]&&vis[p[j].x-disy][p[j].y+disx])
ans++;
}
}
printf("%d\n",ans/4);
}
return 0;
}