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;
}

  

posted @ 2011-07-19 19:06  georgechen_ena  阅读(160)  评论(0)    收藏  举报