POJ 1971 Parallelogram Counting(hash)
2016-07-29 10:28
295 查看
Parallelogram Counting
Description
There are n distinct points in the plane, given by their integer coordinates. Find the number of parallelograms whose vertices lie on these points. In other words, find the number of 4-element subsets of these points that can be written as {A, B, C, D} such
that AB || CD, and BC || AD. No four points are in a straight line.
Input
The first line of the input contains a single integer t (1 <= t <= 10), the number of test cases. It is followed by the input data for each test case.
The first line of each test case contains an integer n (1 <= n <= 1000). Each of the next n lines, contains 2 space-separated integers x and y (the coordinates of a point) with magnitude (absolute value) of no more than 1000000000.
Output
Output should contain t lines.
Line i contains an integer showing the number of the parallelograms as described above for test case i.
Sample Input
Sample Output
Source
Tehran Sharif 2004 Preliminary
这道题的思路很简单,枚举所有线段的中点,每两个相同的中点可以确定一个平行四边形
对于判定相同的中点,一开始我用STL map试了一下,果断超时了
只能用hash了,hash函数的设计很重要,这里用的是折叠法,具体思路我上一篇博客有介绍
另外, hash冲突肯定会有的,这里用开放定址来解决
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <utility>
#include <map>
using namespace std;
typedef pair<int, int> PII;
const int MAXN = 1E3 + 5;
const int MOD = 1e6 + 39;
struct HashCheck {
int x, y;
} hashCheck[MOD];
int t, n, x[MAXN], y[MAXN];
int hashMap[MOD];
//折叠法随便hash一下
int Hash(int x, int y) {
int h = ((x << 2) + (x >> 4)) ^ (y << 9);
h %= MOD;
return h < 0 ? h + MOD : h;
}
void Insert(int x, int y) {
int hash = Hash(x, y);
bool yes = false;
if (hashMap[hash] == 0) {
++hashMap[hash];
hashCheck[hash].x = x;
hashCheck[hash].y = y;
}
else if (hashMap[hash] != 0 && hashCheck[hash].x == x && hashCheck[hash].y == y) {
++hashMap[hash];
}
else {
//开放定址法解决hash冲突
for (int i = hash + 1; ; ++i) {
if (i == MOD) i = 0;
if (hashMap[i] == 0) {
++hashMap[i];
hashCheck[i].x = x;
hashCheck[i].y = y;
break;
}
else if (hashMap[i] != 0 && hashCheck[i].x == x && hashCheck[i].y == y) {
++hashMap[i];
break;
}
}
}
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
scanf("%d", &t);
while (t--) {
scanf("%d", &n);
for (int i = 0; i < n; ++i) {
scanf("%d%d", &x[i], &y[i]);
}
memset(hashMap, 0, sizeof(hashMap));
memset(hashCheck, 0x3f, sizeof(hashCheck));
for (int i = 0; i < n; ++i) {
for (int j = i + 1; j < n; ++j) {
int mx = x[i] + x[j];
int my = y[i] + y[j];
Insert(mx, my);
}
}
int ans = 0;
for (int i = 0; i < MOD; ++i) {
if (hashMap[i] >= 2) ans += hashMap[i] * (hashMap[i] - 1) / 2;
}
printf("%d\n", ans);
}
return 0;
}
Time Limit: 5000MS | Memory Limit: 65536K | |
Total Submissions: 6181 | Accepted: 2119 |
There are n distinct points in the plane, given by their integer coordinates. Find the number of parallelograms whose vertices lie on these points. In other words, find the number of 4-element subsets of these points that can be written as {A, B, C, D} such
that AB || CD, and BC || AD. No four points are in a straight line.
Input
The first line of the input contains a single integer t (1 <= t <= 10), the number of test cases. It is followed by the input data for each test case.
The first line of each test case contains an integer n (1 <= n <= 1000). Each of the next n lines, contains 2 space-separated integers x and y (the coordinates of a point) with magnitude (absolute value) of no more than 1000000000.
Output
Output should contain t lines.
Line i contains an integer showing the number of the parallelograms as described above for test case i.
Sample Input
2 6 0 0 2 0 4 0 1 1 3 1 5 1 7 -2 -1 8 9 5 7 1 1 4 8 2 0 9 8
Sample Output
5 6
Source
Tehran Sharif 2004 Preliminary
这道题的思路很简单,枚举所有线段的中点,每两个相同的中点可以确定一个平行四边形
对于判定相同的中点,一开始我用STL map试了一下,果断超时了
只能用hash了,hash函数的设计很重要,这里用的是折叠法,具体思路我上一篇博客有介绍
另外, hash冲突肯定会有的,这里用开放定址来解决
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <utility>
#include <map>
using namespace std;
typedef pair<int, int> PII;
const int MAXN = 1E3 + 5;
const int MOD = 1e6 + 39;
struct HashCheck {
int x, y;
} hashCheck[MOD];
int t, n, x[MAXN], y[MAXN];
int hashMap[MOD];
//折叠法随便hash一下
int Hash(int x, int y) {
int h = ((x << 2) + (x >> 4)) ^ (y << 9);
h %= MOD;
return h < 0 ? h + MOD : h;
}
void Insert(int x, int y) {
int hash = Hash(x, y);
bool yes = false;
if (hashMap[hash] == 0) {
++hashMap[hash];
hashCheck[hash].x = x;
hashCheck[hash].y = y;
}
else if (hashMap[hash] != 0 && hashCheck[hash].x == x && hashCheck[hash].y == y) {
++hashMap[hash];
}
else {
//开放定址法解决hash冲突
for (int i = hash + 1; ; ++i) {
if (i == MOD) i = 0;
if (hashMap[i] == 0) {
++hashMap[i];
hashCheck[i].x = x;
hashCheck[i].y = y;
break;
}
else if (hashMap[i] != 0 && hashCheck[i].x == x && hashCheck[i].y == y) {
++hashMap[i];
break;
}
}
}
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
scanf("%d", &t);
while (t--) {
scanf("%d", &n);
for (int i = 0; i < n; ++i) {
scanf("%d%d", &x[i], &y[i]);
}
memset(hashMap, 0, sizeof(hashMap));
memset(hashCheck, 0x3f, sizeof(hashCheck));
for (int i = 0; i < n; ++i) {
for (int j = i + 1; j < n; ++j) {
int mx = x[i] + x[j];
int my = y[i] + y[j];
Insert(mx, my);
}
}
int ans = 0;
for (int i = 0; i < MOD; ++i) {
if (hashMap[i] >= 2) ans += hashMap[i] * (hashMap[i] - 1) / 2;
}
printf("%d\n", ans);
}
return 0;
}
相关文章推荐
- POJ 1971 Parallelogram Counting (Hash)
- POJ1971 Parallelogram Counting(hash)
- POJ 1971 Parallelogram Counting(枚举+HASH)
- Spell checker - poj 1035 (hash)
- poj 2697 A Board Game(bfs+hash)
- poj 2002 hash
- POJ 2002 hash(枚举+哈希) 或者 枚举+二分
- POJ 1200 Hash
- Hash poj2002 Squares
- POJ 1743 Musical Theme (字符串HASH+二分)
- POJ - 1840 hash去重
- POJ 2503 Babelfish (Hash)
- Poj 2002 Squares (正方形个数 Hash)
- POJ_2418_hash_map
- POJ 1200 Crazy Search(字符串简单的hash)
- POJ 1200 Crazy Search (字符串hash)
- POJ 1840 Eqs(简单hash入门)
- POJ 1840 hash
- POJ-1200 Crazy Search ( hash )
- POJ 3690 Constellations 简单hash