hdu 6055 or poj 2002

Regular polygon

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 2924    Accepted Submission(s): 685


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


题意

给你n个点  (n < 500)  让你从这些点中找到所有的正多边形



思路 :

刚开始看到这道题的时候我还想暴力找3-n边形 全找一遍  后来发现其实只有正方形   开方是硬伤

只有正方形就其实还比较好处理了  枚举其中两个点 然后就能用数学方法找到另外两个点了

因为枚举了正方形的四条边  所以最后的答案需要 除四 也就是右移两位

处理这两个点的过程还是有点小技巧的  刚开始看了好久  还是看别人博客看懂的    还是数学方法强

因为这道题中点的范围比较小  所以可以用二维数组来判断一个点是否存在过   但是如果这个范围非常大

那我们其实就需要另一种方法  哈希  没错

哈希的写法我参考了这个人的博客  人家讲的很详细  很厉害

他哈希的方法我看了好长时间  数组模拟链表 尤其是next的用法 第一次看到哈希的小透明表示 “简直绝了!!!”

但是他两次for循环的过程  似乎一次就能完成


点击打开链接 

我写的是矩阵存图


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
struct Node
{
    int x, y;
}p[525];
int idx[555][555];
int solve(int l,int r)
{
    Node a = p[l];
    Node b = p[r];
    int res = 0;
    int dx = a.x - b.x;
    int dy = a.y - b.y;
    if(a.x + dy > 0 && a.y - dx > 0 && b.x + dy > 0 && b.y - dx > 0 && idx[a.x + dy][a.y - dx]
       && idx[b.x + dy][b.y - dx]) res ++;
    if(a.x - dy > 0 && a.y + dx > 0 && b.x - dy > 0 && b.y + dx > 0 && idx[a.x - dy][a.y + dx]
       && idx[b.x - dy][b.y +dx]) res ++;
    return res ;
}
int main()
{
    int n;
    while ( cin >> n ) {
        memset(idx , 0, sizeof(idx));
        for (int i = 0; i < n; i ++) {
             cin >> p[i].x >> p[i].y ;
             p[i].x += 200;p[i].y += 200;
             idx[p[i].x][p[i].y] = 1;
        }

        int ans = 0;
        for (int i = 0; i < n; i ++)
            for(int j = i + 1; j < n; j ++)
                ans += solve(i , j);
        ans >>= 2;
        cout << ans  << endl;
    }
}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值