P1665 正方形计数
思路:
很显然是枚举对角线的点,关键在于枚举出对角线端点后怎么求另外两个点.
大佬有详细的证明,我就不画了...GO
要注意的是如果是正方形,一个正方形的对角线会枚举两次,因此答案要>>1.坐标右移并*2是避免小数和负数.
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 typedef pair<int,int> PII; 6 const int N = 510,M = 410; 7 int n,ans; 8 bool st[M][M]; 9 PII p[N]; 10 int main() 11 { 12 scanf("%d",&n); 13 for(int i=1;i<=n;i++) 14 { 15 scanf("%d%d",&p[i].first,&p[i].second); 16 p[i].first=p[i].first+50<<1; 17 p[i].second=p[i].second+50<<1; 18 st[p[i].first][p[i].second] = 1; 19 } 20 for(int i=1;i<=n;i++) 21 for(int j=i+1;j<=n;j++) 22 { 23 int a = p[i].first,b = p[i].second; 24 int c = p[j].first,d = p[j].second; 25 if(a==c&&b==d) continue; 26 int midx = a+c>>1,midy = d+b>>1; 27 int x3 = midx+d-midy,y3 = midy+midx-c; 28 int x4 = midx+b-midy,y4 = midx+midy-a; 29 if(x3<0||y3<0||x4<0||y4<0) continue; 30 if(st[x3][y3]&&st[x4][y4]) ans++; 31 } 32 printf("%d\n",ans>>1); 33 return 0; 34 }