码迷,mamicode.com
首页 > 其他好文 > 详细

POJ 1971 Parallelogram Counting

时间:2016-05-01 06:24:27      阅读:196      评论:0      收藏:0      [点我收藏+]

标签:

题目链接:

http://poj.org/problem?id=1971

题意:

二维空间给n个任意三点不共线的坐标,问这些点能够组成多少个不同的平行四边形。

题解:

使用的平行四边形的判断条件:对角线互相平分的四边形是平行四边形。

所以我们枚举每一条线段,如果有两条线段的中点是重合的,那么这四个顶点就能构成一个平行四边形,我们也就是说每条线段我们只要维护中点就可以了。

1、map维护中点:(数据比较大,t了)

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<map>
 6 #include<utility>
 7 using namespace std;
 8 typedef long long LL;
 9 
10 const int maxn = 1111;
11 
12 int n;
13 int x[maxn],y[maxn];
14 map<pair<int,int>,int> mp;
15 
16 void init(){
17     mp.clear();
18 }
19 
20 int main(){
21     int tc;
22     scanf("%d",&tc);
23     while(tc--){
24         init();
25         scanf("%d",&n);
26         for(int i=0;i<n;i++){
27             scanf("%d%d",x+i,y+i);
28         }
29         int ans=0;
30         for(int i=0;i<n;i++){
31             for(int j=i+1;j<n;j++){
32                 ans+=mp[make_pair(x[i]+x[j],y[i]+y[j])];
33                 mp[make_pair(x[i]+x[j],y[i]+y[j])]++;
34             }
35         }
36         printf("%d\n",ans);
37     }
38     return 0;
39 }

2、用hash做(vector来建表)

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<map>
 6 #include<utility>
 7 #include<vector>
 8 using namespace std;
 9 typedef long long LL;
10 
11 const int maxn = 1111;
12 //可能是因为vector<int> 的初始化影响很大
13 //1e3+7跑2985MS 1e4+7跑1282MS 1e5+7跑1750MS 1e6+7跑4532MS 
14 const int mod = 1e3+7;
15 
16 struct Point {
17     int x, y, cnt;
18     Point(int x, int y, int cnt = 0) :x(x), y(y), cnt(cnt) {}
19     Point() { cnt = 0; }
20 }pt[maxn];
21 
22 int n;
23 vector<Point> tab[mod];
24 int Hash(const Point& p) {
25     //LL tmp = (p.x) *1000000007 + p.y; 
26     int tmp = ((p.x << 2) + (p.x >> 4)) ^ (p.y << 10); //折叠法,比上面一个稍微快一点
27     //注意哈希出来的要是非负数
28     tmp = (tmp%mod + mod) % mod;
29     return tmp;
30 }
31 
32 int add(const Point& p) {
33     int key = Hash(p);
34     int pos = -1;
35     for (int i = 0; i<tab[key].size(); i++) {
36         Point& tmp = tab[key][i];
37         if (p.x == tmp.x&&p.y == tmp.y) {
38             pos = i; break;
39         }
40     }
41     int ret = 0;
42     if (pos == -1) {
43         tab[key].push_back(Point(p.x, p.y, 1));
44     }
45     else {
46         ret = tab[key][pos].cnt;
47         tab[key][pos].cnt++;
48     }
49     return ret;
50 }
51 
52 void init() {
53     for (int i = 0; i<mod; i++) tab[i].clear();
54 }
55 
56 int main() {
57     int tc;
58     scanf("%d", &tc);
59     while (tc--) {
60         init();
61         scanf("%d", &n);
62         for (int i = 0; i<n; i++) {
63             scanf("%d%d", &pt[i].x, &pt[i].y);
64         }
65         int ans = 0;
66         for (int i = 0; i<n; i++) {
67             for (int j = i + 1; j<n; j++) {
68                 Point p = Point(pt[i].x + pt[j].x, pt[i].y + pt[j].y);
69                 ans += add(p);
70             }
71         }
72         printf("%d\n", ans);
73     }
74     return 0;
75 }

3、用邻接表做散列表。

 

POJ 1971 Parallelogram Counting

标签:

原文地址:http://www.cnblogs.com/fenice/p/5449935.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!