LGTB 与正方形
LGTB 最近迷上了正方形,现在他有n 个在二维平面上的点,请你告诉他在这些点中选4 个点能组成四条边都平行于坐标轴的正方形的方案数有多少
输入
输入第一行包含一个整数n,代表点的数量
接下来n 行每行包含两个整数xi, yi,代表点的坐标
对于10% 的数据,1<=n <=50
对于30% 的数据,1<=n<=1000
对于100% 的数据,1<=n<=10^5,0<=xi, yi <=10^5
数据保证没有两点在同一位置
输出
输出包含一个整数代表方案数
样例
样例输入 样例输出
5 1
0 0
0 2
2 0
2 2
1 1
样例输入 样例输出
9 5
0 0
1 1
2 2
0 1
1 0
0 2
2 0
1 2
2 1
好迷哦,这道题,做不来。然而某巨巨还写了一个我看不懂的程序。GG。
那么就大概de说一下。
将原坐标通过x分类,设每个分类为P[x]。如果P[x]中数的个数小于sqrt(n),直接暴力枚举里面元素。(x相同,判断y获取正方形)另外的P[x]暴力枚举这些集合,判断其中那些是y相等的。对于第一类小于sqrt(n)的点的集合,每个集合里面最多sqrt(n)个元素,所以该时间复杂度为O(n sqrt(n))
以上,来自另外一个巨巨。
附STD代码:
#include <set>
#include <cmath>
#include <stack>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <numeric>
#include <vector>
#include <ctime>
#include <queue>
#include <list>
#include <map>
#define pi acos(-1.0)
#define INF 0x3f3f3f3f
#define clr(x) memset(x,0,sizeof(x));
#define clrto(x,siz,y) for(int xx=0;xx<=siz;xx++) x[xx]=y;
#define clrset(x,siz) for(int xx=0;xx<=siz;xx++) x[xx]=xx;
#define clr_1(x) memset(x,-1,sizeof(x));
#define clrmax(x) memset(x,0x3f,sizeof(x));
#define clrvec(x,siz) for(int xx=0;xx<=siz;xx++) x[xx].clear();
#define fop2 freopen(".in","r",stdin); //freopen(".out","w",stdout);
#define fop freopen("in.txt","r",stdin);//freopen("out.txt","w",stdout);
#define myprogram By_135678942570
#define clrcpy(x,siz,y) for(int xx=0;xx<siz;xx++) x[xx]=y[xx];
#define pb push_back
using namespace std;
struct point
{
int x,y;
}P[100011];
int SIZ=400;
struct hash_map
{
const static int mod=100007;
int head[mod];
struct hash_tables
{
long long key;
int val;
int next;
}ele[100007];
int N;
int getHash(long long x)
{
return x%mod;
}
void init()
{
memset(head,255,sizeof(head));
N=0;
}
int fint(long long x)
{
for(int i=head[getHash(x)];i!=-1;i=ele[i].next)
if(ele[i].key==x)
return i;
return -1;
}
void insert(long long x)
{
int tmp=getHash(x);
ele[N].key=x;
ele[N].val=0;
ele[N].next=head[tmp];
head[tmp]=N++;
}
int& operator [](long long x)
{
int tmp=fint(x);
if(tmp==-1)
{
insert(x);
return ele[N-1].val;
}
else return ele[tmp].val;
}
}HT;
vector<int>row[100111];
vector<int>GREAT;
vector<int>LESS;
int main()
{
// fop;
freopen("square.in", "r", stdin);
freopen("square.out", "w", stdout);
HT.init();
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d%d",&P[i].x,&P[i].y);
row[P[i].x].pb(P[i].y);
HT.insert(P[i].x*1000003ll+P[i].y);
}
for(int i=0;i<=100000;i++)
if(row[i].size()>=SIZ)
GREAT.pb(i);
else if(row[i].size()>0)
LESS.pb(i);
int res=0;
for(int i=0;i<LESS.size();i++)
{
int rowid=LESS[i];
for(int j=0;j<row[rowid].size();j++)
for(int k=j+1;k<row[rowid].size();k++)
{
int x1=rowid;
int y1=row[rowid][j],y2=row[rowid][k];
int x2=x1+abs(y1-y2);
int x22=x1-abs(y1-y2);
int f1=HT.fint(x2*1000003ll+y1);
int f2=HT.fint(x2*1000003ll+y2);
if(f1!=-1&&f2!=-1)
{
res++;
}
if(x22>=0&&row[x22].size()>=SIZ)
{
f1=HT.fint(x22*1000003ll+y1);
f2=HT.fint(x22*1000003ll+y2);
if(f1!=-1&&f2!=-1)
res++;
}
}
}
for(int i=0;i<GREAT.size();i++)
sort(row[GREAT[i]].begin(),row[GREAT[i]].end());
for(int i=0;i<GREAT.size();i++)
for(int j=i+1;j<GREAT.size();j++)
{
int x1=GREAT[i];
int x2=GREAT[j];
int len=abs(x1-x2);
int ii=0,jj=0;
while(ii<row[x1].size()&&jj<row[x2].size())
{
if(row[x1][ii]==row[x2][jj])
{
int f1=HT.fint(x1*1000003ll+row[x1][ii]+len);
int f2=HT.fint(x2*1000003ll+row[x2][jj]+len);
if(f1!=-1&&f2!=-1)
res++;
ii++,jj++;
}
else if(row[x1][ii]>row[x2][jj])
jj++;
else ii++;
}
}
printf("%d\n",res);
}