POJ 1971 —— Parallelogram Counting(ZZ)
#include <iostream>
#include <vector>
#include <cstdio>
using namespace std;
const int MAXN = 1001;
const int MAXM = 20000;
const int PRIME = 19997;
struct Node {
int x, y;
}node[MAXN];
struct Point {
int midx, midy, cnt;
};
vector <Point> hash[MAXM];
int resCnt;
void Hash(int sum, Point pt)
{
sum %= PRIME;
vector<Point>::size_type ix, size = hash[sum].size();
for(ix = 0; ix < size; ix ++) {
int midx = hash[sum][ix].midx;
int midy = hash[sum][ix].midy;
if(midx == pt.midx && midy == pt.midy) {
resCnt += hash[sum][ix].cnt;
hash[sum][ix].cnt += pt.cnt;
break;
}
}
if(ix == size)
hash[sum].push_back(pt);
}
int main()
{
int cas;
scanf("%d", &cas);
while(cas --) {
int i, j, n;
scanf("%d", &n);
for(i = 0; i < n; i ++) {
scanf("%d %d", &node[i].x, &node[i].y);
}
for(i = 0; i < PRIME; i ++)
hash[i].clear();
Point pt;
resCnt = 0;
for(i = 0; i < n; i ++) {
for(j = i + 1; j < n; j ++) {
pt.midx = node[i].x + node[j].x; //不除2,保证整数存储
pt.midy = node[i].y + node[j].y;
pt.cnt = 1;
int sum = pt.midx + pt.midy;
if(sum < 0)
sum *= -1;
Hash(sum, pt);
}
}
printf("%d\n", resCnt);
}
return(0);
}
题意:有N个点,求这N个点能组成多少个不同的平行四边形。
思路:平行四边形对角形互相平分,所以枚举两个不同的点,求其中点坐标,如果中点坐标相同,说明能组成平行四边形。具体采用哈希查找。
好像曾经见过类似的题目,千万不要枚举 4 个点。
我的代码
排序过。。。
#include <iostream>
using namespace std;
struct Node
{
int x;
int y;
}a[1024];
Node mid[1024*1024];
int cmp(const void* a, const void* b)
{
Node* c = (Node*)a;
Node* d = (Node*)b;
if(c->x != d->x)
return c->x < d->x ? -1 : 1;
return c->y < d->y ? -1 : 1;
}
int main()
{
int cas, n, i, j, count;
scanf("%d", &cas);
while(cas--)
{
scanf("%d", &n);
count = 0;
for(i = 0; i < n; ++i)
{
scanf("%d%d", &a[i].x, &a[i].y);
for(j = 0; j < i; ++j)
{
mid[count].x = a[i].x + a[j].x;
mid[count].y = a[i].y + a[j].y;
count++;
}
}
qsort(mid, count, sizeof(mid[0]), cmp);
int total = 0, sum = 1;
bool flag = false;
//printf("%d %d\n", mid[0].x, mid[0].y);
for(i = 1; i < count; ++i)
{
//printf("%d %d...\n", mid[i].x, mid[i].y);
if(mid[i].x == mid[i-1].x && mid[i].y == mid[i-1].y)
{
sum++;
flag = true;
}
else
{
if(flag)
{
total += sum*(sum-1)/2;
sum = 1;
}
flag = false;
}
}
printf("%d\n", total);
}
return 0;
}

浙公网安备 33010602011771号