给出N个点,问这些点能组成多少个正方形,N小于1000,显然的,思路是,先确定正方形的两个顶点,然后在点集中查找另外两个顶点
至于查找,有两种做法,一个是二分,一个是hash,很明显,hash要快一些
Node 1:二分 1157ms,具体见代码
#include <iostream> #include <algorithm> #include <cstdio> using namespace std; struct node { int x, y; } p[1001]; bool op(node xx,node yy) { if (xx.x == yy.x) return xx.y < yy.y; else return xx.x < yy.x; } int main() { int points; while (scanf("%d", &points), points) { int sum = 0; for (int k = 0; k < points; ++k) scanf("%d%d", &p[k].x, &p[k].y); sort(p, p + points, op); for (int i = 0; i < points; ++i) { for (int j = i + 1; j < points; ++j) { if(p[i].x <= p[j].x && p[i].y >= p[j].y) { node p0, p1; p0.x = p[i].x + p[j].y - p[i].y; p0.y = p[i].y + p[i].x - p[j].x; p1.x = p[j].x + p[j].y - p[i].y; p1.y = p[j].y + p[i].x - p[j].x; if (!binary_search(p, p+points, p0, op)) continue; if (!binary_search(p, p+points, p1, op)) continue; sum++; } } } printf("%d\n", sum); } return 0; }
Node 2:hash,735ms
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; const int N = 1010; const int Mod = 11117; int ans; struct Point{ int x,y; }p[N]; struct Node{ Point x; Node *next; }node[Mod+10]; bool cmp(Point a,Point b){ if(a.x==b.x)return a.y<b.y; return a.x<b.x; } void insert(Point a){ int key=(a.x*a.x+a.y*a.y)%Mod; Node *newNode = new Node; newNode->x=a; newNode->next = node[key].next; node[key].next = newNode; } int search(Point a){ int key=(a.x*a.x+a.y*a.y)%Mod; Node *shit = &node[key]; while(shit != NULL){ if( shit->x.x == a.x && shit->x.y == a.y)return 1; shit = shit->next; } return 0; } int main() { int i,j,n; while(scanf("%d",&n),n){ memset(node,0,sizeof(node)); for(i=0;i<n;i++){ scanf("%d%d",&p[i].x,&p[i].y); insert(p[i]); } //开始没有排序,下面只是查找了p0,p1两个点,一直wa,因为不排序的话,需要查找4个点,然后结果除以4 sort(p,p+n,cmp); ans=0; for (i = 0; i < n; ++i){ for (j = i + 1; j < n; ++j){ Point p0,p1; p0.x = p[i].x + p[i].y - p[j].y; p0.y = p[i].y - p[i].x + p[j].x; if( !search(p0) )continue; p1.x = p[j].x + p[i].y - p[j].y; p1.y = p[j].y - p[i].x + p[j].x; if( !search(p1) )continue; ans++; } } printf("%d\n",ans/2); } return 0; }