zoukankan      html  css  js  c++  java
  • HDU3982 Harry Potter and J.K.Rowling

    Harry Potter and J.K.Rowling

    In July 31st, last month, the author of the famous novel series J.K.Rowling celebrated her 46th birthday. Many friends gave their best wishes. They gathered together and shared one large beautiful cake.

    Rowling had lots of friends, and she had a knife to cut the cake into many pieces. On the cake there was a cherry. After several cuts, the piece with the cherry was left for Rowling. Before she enjoyed it, she wondered how large this piece was, i.e., she wondered how much percentage of the cake the piece with the only cherry has.

    (nleq 2000)

    题解

    半平面交+凸多边形与圆的面积交。

    然后被精度卡烂了。

    时间复杂度(O(nlog n))

    struct point {double x,y;};
    
    IN point operator+(CO point&a,CO point&b){
    	return (point){a.x+b.x,a.y+b.y};
    }
    IN point operator-(CO point&a,CO point&b){
    	return (point){a.x-b.x,a.y-b.y};
    }
    IN point operator*(CO point&a,double b){
    	return (point){a.x*b,a.y*b};
    }
    IN point operator/(CO point&a,double b){
    	return (point){a.x/b,a.y/b};
    }
    IN double dot(CO point&a,CO point&b){
    	return a.x*b.x+a.y*b.y;
    }
    IN double cross(CO point&a,CO point&b){
    	return a.x*b.y-a.y*b.x;
    }
    IN double len(CO point&a){
    	return sqrt(dot(a,a));
    }
    IN double angle(CO point&a,CO point&b){
    	double w=dot(a,b)/len(a)/len(b);
    	w=max(w,-1.0),w=min(w,1.0); // edit 3
    	return acos(w);
    }
    
    struct line {point x,y;};
    
    IN bool on_left(CO point&a,CO line&b){
    	return cross(a-b.x,b.y)<0;
    }
    IN int quad(CO point&a){
    	if(a.x>0 and a.y>=0) return 1;
    	else if(a.x<=0 and a.y>0) return 2;
    	else if(a.x<0 and a.y<=0) return 3;
    	else return 4;
    }
    IN bool operator<(CO line&a,CO line&b){
    	if(quad(a.y)!=quad(b.y)) return quad(a.y)<quad(b.y);
    	return cross(a.y,b.y)==0?on_left(a.x,b):cross(a.y,b.y)>0; // edit 2
    }
    IN point intersect(CO line&a,CO line&b){
    	return b.x+b.y*cross(b.x-a.x,a.y)/cross(a.y,b.y);
    }
    
    CO double pi=acos(-1),eps=1e-6;
    
    vector<point> seg_cross_circle(CO point&a,CO point&b,double r){
    	double dx=b.x-a.x,dy=b.y-a.y;
    	double A=dx*dx+dy*dy;
    	double B=2*dx*a.x+2*dy*a.y; // edit 1
    	double C=a.x*a.x+a.y*a.y-r*r;
    	double delta=B*B-4*A*C;
    	vector<point> ans;
    	if(delta<-eps) return ans; // edit 2
    	delta=sqrt(max(delta,0.0));
    	double t1=(-B+delta)/(2*A);
    	double t2=(-B-delta)/(2*A);
    	if(-t1<eps and t1-1<eps) // edit 3
    		ans.push_back((point){a.x+t1*dx,a.y+t1*dy});
    	if(-t2<eps and t2-1<eps)
    		ans.push_back((point){a.x+t2*dx,a.y+t2*dy});
    	return ans;
    }
    double triangle_cross_circle(point a,point b,double r){
    //	cerr<<"a="<<a.x<<" "<<a.y<<" b="<<b.x<<" "<<b.y<<endl;
    	bool AinC=dot(a,a)<r*r,BinC=dot(b,b)<r*r;
    	double sign=0.5*(cross(a,b)>0?1:-1),ans=0;
    	if(AinC and BinC) ans=abs(cross(a,b)); // edit 4
    	else if(AinC or BinC){
    		if(BinC) swap(a,b);
    		vector<point> tmp=seg_cross_circle(a,b,r);
    		ans=abs(cross(a,tmp[0]))+r*r*angle(tmp[0],b);
    	}
    	else{
    		vector<point> p=seg_cross_circle(a,b,r);
    		ans=r*r*angle(a,b);
    		if(p.size()==2){
    			ans-=r*r*angle(p[0],p[1]);
    			ans+=abs(cross(p[0],p[1]));
    		}
    	}
    //	cerr<<"ans="<<ans<<endl;
    	return ans*=sign;
    }
    
    CO int N=2e3+10;
    point p[N];
    line ln[N];
    
    int halfplane(int n){
    	sort(ln+1,ln+n+1);
    	int m=1;
    	for(int i=2;i<=n;++i){
    		if(cross(ln[i].y,ln[m].y)==0) continue;
    		ln[++m]=ln[i];
    	}
    	int l=1,r=1;
    	for(int i=2;i<=m;++i){
    		for(;l<r and !on_left(p[r],ln[i]);--r);
    		for(;l<r and !on_left(p[l+1],ln[i]);++l);
    		ln[++r]=ln[i];
    		if(l<r) p[r]=intersect(ln[r-1],ln[r]);
    	}
    	for(;l<r and !on_left(p[r],ln[l]);--r);
    	if(l<r) p[l]=p[r+1]=intersect(ln[l],ln[r]);
    	for(int i=1;i<=r-l+1;++i) p[i]=p[l+i-1];
    	return r-l+1;
    }
    void real_main(){
    	double r;scanf("%lf",&r);
    	int n=4+read<int>();
    	ln[1].x=(point){0,-r},ln[1].y=(point){1,0};
    	ln[2].x=(point){r,0},ln[2].y=(point){0,1};
    	ln[3].x=(point){0,r},ln[3].y=(point){-1,0};
    	ln[4].x=(point){-r,0},ln[4].y=(point){0,-1};
    	for(int i=5;i<=n;++i){
    		point a,b;scanf("%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y);
    		ln[i].x=a,ln[i].y=b-a;
    	}
    	point o;scanf("%lf%lf",&o.x,&o.y);
    	for(int i=5;i<=n;++i)
    		if(!on_left(o,ln[i])) ln[i].y=ln[i].y*-1;
    	n=halfplane(n),p[n+1]=p[1];
    //	cerr<<"p=";
    //	for(int i=1;i<=n+1;++i)
    //		cerr<<" ("<<p[i].x<<","<<p[i].y<<")"<<endl;
    	double ans=0;
    	for(int i=1;i<=n;++i)
    		ans+=triangle_cross_circle(p[i],p[i+1],r);
    	ans=ans/(pi*r*r);
    	printf("%.5lf%%
    ",100*ans);
    }
    int main(){
    	int T=read<int>();
    	for(int i=1;i<=T;++i){
    		printf("Case %d: ",i);
    		real_main();
    	}
    	return 0;
    }
    
  • 相关阅读:
    未来 3-5 年信息安全行业会如何变化,目前可以观察到的变化有哪些?
    信息安全经典书籍
    Apparmor——Linux内核中的强制访问控制系统
    深入理解SELinux
    FreebuF黑客专访系列之吴翰清(刺):接下来几年,有两样东西必定会火
    Security Checklist (路由器安全checklist)
    CPU MPU MCU SOC SOPC关系及区别
    军火库(第一期):无线电硬件安全大牛都用哪些利器?
    华为V-ISA信誉安全体系:对付新型DDoS攻击的利器
    物联网兴起 嵌入式系统安全日益受关注
  • 原文地址:https://www.cnblogs.com/autoint/p/13185688.html
Copyright © 2011-2022 走看看