BZOJ 2592 随机化(伪)
思路:
放yousiki大爷题解
http://yousiki.net/index.php/archives/82/
我写的是随机化
既然gzz证了最终答案的上界是O(N)的
那么我们可以n^2枚举所有的点对
先pretest判一发 (随机10个点 找找有没有对称点) 如果过了pretest再O(n)的判
整体复杂度是$O(n^2logn)$的
//By SiriusRen #include <bits/stdc++.h> using namespace std; const int mod=10000019,N=1050; int n,xx,yy,ans=0; struct Point{double x,y;Point(){}Point(double X,double Y){x=X,y=Y;}}point[N]; Point operator-(Point a,Point b){return Point(a.x-b.x,a.y-b.y);} double operator*(Point a,Point b){return a.x*b.y-a.y*b.x;} bool operator<(Point a,Point b){if(a.x==b.x)return a.y<b.y;return a.x<b.x;} struct Line{Point a,b;Line(){}Line(Point X,Point Y){a=X,b=Y;}}stk[N*100]; Line get_line(int i,int j){ Point x=Point((point[i].x+point[j].x)/2,(point[i].y+point[j].y)/2); Point y=Point(x.x+point[j].y-point[i].y,x.y-point[j].x+point[i].x); return Line(x,y); } double dis(Point a,Point b){a=a-b;return sqrt(a.x*a.x+a.y*a.y);} Point get_point(Point p,Line ln){ double d=(ln.b-ln.a)*(p-ln.a)/dis(ln.a,ln.b)*2,x=ln.b.y-ln.a.y,y=ln.a.x-ln.b.x,s=sqrt(x*x+y*y); return Point(p.x+x*d/s,p.y+y*d/s); } bool pretest(Line ln){ for(int i=1;i<=10;i++){ Point p=get_point(point[rand()%n+1],ln); double x=round(p.x),y=round(p.y); if(abs(x-p.x)>1e-7||abs(y-p.y)>1e-7)return 0; Point f=Point(x,y); int t=lower_bound(point+1,point+1+n,f)-point; if(t>n||abs(point[t].x-f.x)>1e-7||abs(point[t].y-f.y)>1e-7)return 0; }return 1; } bool test(Line ln){ for(int i=1;i<=n;i++){ Point p=get_point(point[i],ln); double x=round(p.x),y=round(p.y); if(abs(x-p.x)>1e-7||abs(y-p.y)>1e-7)return 0; Point f=Point(x,y); int t=lower_bound(point+1,point+1+n,f)-point; if(t>n||abs(point[t].x-f.x)>1e-7||abs(point[t].y-f.y)>1e-7)return 0; }return 1; } bool check(Line tmp){for(int i=1;i<=ans;i++)if(abs((stk[i].a-stk[i].b)*(tmp.a-tmp.b))<1e-7)return 0;return 1;} int main(){ srand(1005730820);scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d%d",&xx,&yy),point[i]=Point(1.0*xx,1.0*yy); sort(point+1,point+1+n); for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++){ Line tmp=get_line(i,j); if(check(tmp)&&pretest(tmp)&&test(tmp))stk[++ans]=tmp; tmp=Line(point[i],point[j]); if(check(tmp)&&pretest(tmp)&&test(tmp))stk[++ans]=tmp; } printf("%d\n",ans); }