题解 P1665 【正方形计数】
zhangziyi_xshsnoi
·
·
题解
简单的三垂直问题
引入
学过全等三角形的都知道三垂直
如图
则易证$AM=BN,MB=CN
把他用到坐标中,与正方形结合
如图一
坐标系上有两点A,B。A(2,4),B(4,0);
如图二
坐标系上有另外两点C,D
如图三
坐标系上另有两点C',D'

$C'(-2,2),D'(0,-2)$使四边形AC'BD'也是正方形
```cpp
struct node
{
int x,y;
}num[3000];
A(num[i].x,num[i].y) B(num[j].x,num[j].y);
```
若使ABCD为正方形
则
```
C(num[i].x±(num[i].x-num[j].x),num[i].y±(num[j].y-num[i].y))
D(num[j].x±(num[i].x-num[j].x),num[j].y±(num[j].y-num[i].y))
```
所以这道$\color{purple} \text{\textbf{黄题}}$最后只要判断C点,D点是否存在就行了
------------
# **上DM**
```cpp
#include<bits/stdc++.h>
using namespace std;
inline int read(){
int w=1,q=0;char ch=' ';
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')w=-1,ch=getchar();
while(ch>='0'&&ch<='9')q=q*10+ch-'0',ch=getchar();
return w*q;
}//快读
struct node
{
int x,y;
}num[3000];
map<pair<int,int>,int >mapp;//因为坐标有负数,所以用map+pair
int n,tot=0,ans=0;
int main()
{
//freopen("rect.in","r",stdin);
//freopen("rect.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
int a,b;
a=read(),b=read();
num[i].x=a,num[i].y=b;
mapp[make_pair(a,b)]=1;
}
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
{
int u,v;
u=num[i].x-num[j].x;
v=num[j].y-num[i].y;
if(mapp[make_pair(num[i].x+v,num[i].y+u)]==1&&mapp[make_pair(num[j].x+v,num[j].y+u)]==1)
ans++;
if(mapp[make_pair(num[i].x-v,num[i].y-u)]==1&&mapp[make_pair(num[j].x-v,num[j].y-u)]==1)
ans++;
}
printf("%d",ans/4);//一个正方形重复四遍,所以要除以4
}
```
//重新审核
//增加了Latex,求通过
//<蒟蒻的第一篇题解>