http://poj.org/problem?id=2002
题意 : 就是给你很多点的坐标,任取四个,看能组成多少个不同的正方形,相同的四个点,不同顺序构成的正方形视为同一正方形。
思路 : 就是一个简单的枚举,但是你要是四个点四个点的枚举因为数据量到1000,所以肯定会超时的,就两个点两个点枚举,再去判断另外两个点是否存在就可以了,百度了才知道有这样一个公式,知道两个点(x1,y1)(x2,y2)
x3=x1+(y1-y2) y3= y1-(x1-x2)
x4=x2+(y1-y2) y4= y2-(x1-x2)
或
x3=x1-(y1-y2) y3= y1+(x1-x2)
x4=x2-(y1-y2) y4= y2+(x1-x2)
据说是通过三角形全等证出来的
不过最后的结果要除以4,因为你每个点都枚举到了,所以就重复的加了一个正方形4次
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<cstdio> #include<cstring> #include<cstdio> using namespace std ; const int maxn = 2500 ; bool vis[maxn<<1][maxn<<1];//这个要定义成bool类型的,定义成int类型的会超内存 int ch[maxn],sh[maxn] ; int main() { int n; while(scanf("%d",&n)&&n) { memset(vis,0,sizeof(vis)) ; int a,b ; int cnt = 0 ; for(int i = 1 ; i <= n ; i++) { scanf("%d %d",&a,&b) ; ch[i] = a ; sh[i] = b ; vis[maxn+a][maxn+b] = 1 ;//因为存在负坐标,而数组下标只能为正 } int x1,x2,x3,x4,y1,y2,y3,y4 ; for(int i = 2 ; i <= n ; i++) { x1 = ch[i] ; y1 = sh[i] ; for(int j = 1 ; j < i ; j++) { x2 = ch[j] ; y2 = sh[j] ; x3=x1+(y1-y2); y3= y1-(x1-x2); x4=x2+(y1-y2); y4= y2-(x1-x2); if(vis[x3+maxn][y3+maxn]&&vis[x4+maxn][y4+maxn]) cnt++ ; x3=x1-(y1-y2); y3= y1+(x1-x2); x4=x2-(y1-y2); y4= y2+(x1-x2); if(vis[x3+maxn][y3+maxn]&&vis[x4+maxn][y4+maxn]) cnt++ ; } } printf("%d\n",cnt>>2) ; } return 0 ; }