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 }

 

posted @ 2021-03-11 09:18  acmloser  阅读(96)  评论(0编辑  收藏  举报