一开始的时候我是枚举正方形的中心,结果wa了一下午,水平太菜了。
正确的方法是每次枚举两个点,然后就能计算出另外4个点的坐标(对于常年没数学的还是在纸上一笔一划的把点坐标求出来)
然后这样结果会是4倍,结果/4即可。
还有一点,我虽然知道多关键字排序,但是稍微变一下我就不会了。。。。
用pair<int,int>代表坐标,然后按这两个关键字进行排序,这样找点的时候就能二分查找了。
所以这道题目对于水平不行得人来说有两个坑。
1、求坐标的时候没有求准确。
2、没想到对坐标按x和y作为俩个关键字进行排序。
重点:
最后把代码交上去,发现自己傻逼了,其实根本不用排序,直接开一个大数组存储下来即可。
所以,水平不够要多想多练。
n^2logn的代码:
#include<iostream>
#include<cstdio>
#include<set>
using namespace std;
set< pair<int,int> > s;//点集,用于二分查找
pair<int,int> ps[505];//点集
int main()
{
int n;
while(scanf("%d",&n)==1)
{
int x,y;
s.clear();
for(int i=1;i<=n;i++)
{
scanf("%d%d",&x,&y);
ps[i].first=x;
ps[i].second=y;
s.insert(ps[i]);
}
int ans=0;
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
int x1=ps[i].first,y1=ps[i].second;
int x2=ps[j].first,y2=ps[j].second;
if(s.count(pair<int,int>(x2+y1-y2,y2+x2-x1))&&s.count(pair<int,int>(x1+y1-y2,y1+x2-x1)))
ans++;
if(s.count(pair<int,int>(x2-(y1-y2),y2-(x2-x1)))&&s.count(pair<int,int>(x1-(y1-y2),y1-(x2-x1))))
ans++;
}
}
printf("%d\n",ans/4);
}
}
n^2的代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int s[700][700];//点集,用于直接查找
pair<int,int> ps[505];//点集
int main()
{
int n;
while(scanf("%d",&n)==1)
{
int x,y;
memset(s,0,sizeof(s));
for(int i=1;i<=n;i++)
{
scanf("%d%d",&x,&y);
ps[i].first=x;
ps[i].second=y;
s[x+350][y+350]=1;
}
int ans=0;
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
int x1=ps[i].first,y1=ps[i].second;
int x2=ps[j].first,y2=ps[j].second;
if(s[x2+y1-y2+350][y2+x2-x1+350]&&s[x1+y1-y2+350][y1+x2-x1+350])
ans++;
if(s[x2-(y1-y2)+350][y2-(x2-x1)+350]&&s[x1-(y1-y2)+350][y1-(x2-x1)+350])
ans++;
}
}
printf("%d\n",ans/4);
}
}