標籤:codeforces 雜題
題意:
平面上有n個點 問 最多能組成多少個邊與座標軸平行的正方形
思路:
這是一個通過不斷二分尋找亂搞的題…
首先枚舉左下角 然後分別往上往右找左上方和右下角
這時如果發現邊長不想等就通過長邊長度在短邊的方向二分尋找最接近的值 不停往上往右延伸
如果發現邊長想等了 那麼要判斷一下對應的左上方座標出是不是有一個點
怎麼判斷呢 通過將所有點hash出一個值 然後二分…
反正這題就是各種二分亂搞 - -b 複雜度不好算 大概是n*(同x的點數+同y的點數)
代碼:
#include<cstdio>#include<cstring>#include<algorithm>#include<vector>using namespace std;#define N 100010#define LL __int64struct node{ int x,y;}nd[N];vector<int> x[N],y[N];int n,ans;LL hashnode[N];bool cmpx(node fa,node fb){ if(fa.x==fb.x) return fa.y<fb.y; return fa.x<fb.x;}bool cmpy(node fa,node fb){ if(fa.y==fb.y) return fa.x<fb.x; return fa.y<fb.y;}int main(){ int i,l,r,u,d,idx,idy,sx,sy,tmp; scanf("%d",&n); for(i=1;i<=n;i++) { scanf("%d%d",&nd[i].x,&nd[i].y); hashnode[i]=(LL)nd[i].x*200000+nd[i].y; } sort(nd+1,nd+n+1,cmpx); for(i=1;i<=n;i++) x[nd[i].x].push_back(nd[i].y); sort(nd+1,nd+n+1,cmpy); for(i=1;i<=n;i++) y[nd[i].y].push_back(nd[i].x); hashnode[n+1]=(1ULL<<63)-1; sort(hashnode+1,hashnode+n+1); for(i=1;i<=n;i++) { d=nd[i].x; l=nd[i].y; idx=lower_bound(x[d].begin(),x[d].end(),l)-x[d].begin()+1; idy=lower_bound(y[l].begin(),y[l].end(),d)-y[l].begin()+1; sx=x[d].size(); sy=y[l].size(); while(idx<sx&&idy<sy) { u=y[l][idy]; r=x[d][idx]; if(u-d==r-l) { tmp=lower_bound(hashnode+1,hashnode+n+2,(LL)u*200000+r)-hashnode; if(hashnode[tmp]==(LL)u*200000+r) ans++; idx++; idy++; } else if(u-d<r-l) idy=lower_bound(y[l].begin(),y[l].end(),d-l+r)-y[l].begin(); else if(u-d>r-l) idx=lower_bound(x[d].begin(),x[d].end(),l-d+u)-x[d].begin(); } } printf("%d\n",ans); return 0;}