您的位置:首页 > 大数据 > 人工智能

HDU6055 Regular polygon 2017 Multi-University Training Contest - Team 2

2017-07-28 16:41 423 查看

Regular polygon

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

Total Submission(s): 2924    Accepted Submission(s): 685


[align=left]Problem Description[/align]
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.
 

[align=left]Input[/align]
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.)
 

[align=left]Output[/align]
For each case, output a number means how many different regular polygon these points can make.
 

[align=left]Sample Input[/align]

4
0 0
0 1
1 0
1 1
6
0 0
0 1
1 0
1 1
2 0
2 1

 

[align=left]Sample Output[/align]

1
2

题目意思:给你n个整数点,问这n个整数点内能构成多少个正多边形。

官方解释:题意,二维平面上给N个整数点,问能构成多少个不同的正多边形。 题解:容易得知只有正四边形可以使得所有的顶点为整数点。(具体证明可参考杨景钦在2017的国家队论文) 所以正解即求出所有的正四边形个数。 枚举2个点,然后暴力判断另外2个点的位置是否存在。 复杂度 N*N*logN。

因为点的数量最多为500 所以可以考虑暴力求解。

涉及到的知识点有,哈希表,链式前向星存储,暴力求解。

链式前向星不懂的可以看这个博客,讲的很详细:http://blog.csdn.net/acdreamers/article/details/16902023

哈希表:http://www.cnblogs.com/dolphin0520/archive/2012/09/28/2700000.html

代码如下:

/*
2017年7月28日16:34:20
AC代码
*/

#include<stdio.h>
#include<string.h>
#include<math.h>
using namespace std;
typedef long long ll;
const ll mod=1010;
const ll maxn=550;
struct node{
ll x;
ll y;
ll next;
}A[maxn];

ll X[maxn],Y[maxn];
ll H[mod];
ll node,n,ans;
/*
对每个坐标进行存储
利用哈希表 ,将二维坐标通过 key=(x*x+y*y)%mod这种计算方式映射到一维
这里也利用了链式前向星的存储方式,

*/
void insert(int x,int y){
int key=(x*x+y*y)%mod;
A[node].x=x;A[node].y=y;
A[node].next=H[key];
H[key]=node++;
//printf("H[%d]=%d\n",key,node-1);//大家要是不懂这种存储方式,可以把这两句printf()加上,看看这几个点在H[] 和 A[] 中到底是怎么存储的
//printf("A[%d].x=%d A[%d].y=%d A[%d].next=%d\n",node-1,A[node-1].x,node-1,A[node-1].y,node-1,A[node-1].next);
}

bool search(int x,int y){
int key=(x*x+y*y)%mod;
/*
链式前向星的遍历方式
*/
for(int k=H[key];k!=-1;k=A[k].next){
if(A[k].x==x&&A[k].y==y) return true;
}
return false;
}

int main(){
while(scanf("%d",&n)==1){
node=0;
ans=0;
memset(H,-1,sizeof(H));
for(int i=1;i<=n;i++){
scanf("%d%d",&X[i],&Y[i]);
insert(X[i],Y[i]);
}
/*
for(int i=0;i<node;i++){
printf("A[%d].x=%d A[%d].y=%d A[%d].next=%d\n",i,A[i].x,i,A[i].y,i,A[i].next);
}
*/

for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
int x1,x2,y1,y2;
x1=X[i]-(Y[i]-Y[j]);
y1=Y[i]+(X[i]-X[j]);
x2=X[j]-(Y[i]-Y[j]);
y2=Y[j]+(X[i]-X[j]);
if(search(x1,y1)&&search(x2,y2))	ans++;
x1=X[i]+(Y[i]-Y[j]);
y1=Y[i]-(X[i]-X[j]);
x2=X[j]+(Y[i]-Y[j]);
y2=Y[j]-(X[i]-X[j]);
if(search(x1,y1)&&search(x2,y2))	ans++;
}
}
/*
考虑到每一条边都可以作为一个正四边形的四条边来算,
所以最后的结果要除以4
*/
printf("%d\n",ans/4);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐