LA 2572 圆盘的相互覆盖问题,圆弧极角排序,中点代替圆弧,轻微扰动的影响判断
来源:互联网 发布:淘宝体检中心链接 编辑:程序博客网 时间:2024/04/30 00:38
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<string>#include<set>#include<vector>#include<map>#define LL long longusing namespace std;const double eps=5*1e-13;const double PI=acos(-1.0);int dcmp(double x){ if(fabs(x)<eps) return 0; return x>0?1:-1;}struct point{ double x,y; point() {} point(double x,double y):x(x),y(y){} point operator + (const point &a) const { return point(x+a.x,y+a.y); } point operator - (const point &a) const { return point(x-a.x,y-a.y); } point operator * (const double &a) const { return point(x*a,y*a); } point operator / (const double &a) const { return point(x/a,y/a); } bool operator <(const point &a) const { return (x+eps<a.x||(!dcmp(x-a.x)&&y<a.y)); } double len() { return sqrt(x*x+y*y); } point normal() { return point(-y,x)/len(); } void in() { cin>>x>>y; }};double dis(point a,point b){ return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}double angle(point v){ return atan2(v.y,v.x);}struct Circle{ point o; double r; Circle() {} Circle(point o,double r):o(o),r(r){} point getpoint(double a) { return point(r*cos(a),r*sin(a))+o; } void in() { o.in(); cin>>r; }};void getCircleCircleIntersection(Circle C1,Circle C2,vector<double> &sol){ point u=C1.o-C2.o; double d=u.len(); if(dcmp(d)==0) return ; if(dcmp(C1.r+C2.r-d)<0) return ; if(dcmp(fabs(C1.r-C2.r)-d)>0) return ; double a=angle(C2.o-C1.o); double da=acos((C1.r*C1.r+d*d-C2.r*C2.r)/(2*C1.r*d)); sol.push_back(a+da); sol.push_back(a-da);}Circle C[110];int n;int topmost(point p){ // cout<<p.x<<" "<<p.y<<endl; for(int i=n-1;i>=0;i--) { // cout<<dis(C[i].o,p)<<endl; if(dis(C[i].o,p)<C[i].r) return i; } return -1;}int main(){ while(cin>>n&&n) { for(int i=0;i<n;i++) C[i].in(); set<int> ret; for(int i=0;i<n;i++) { vector<double> sol; for(int j=0;j<n;j++) getCircleCircleIntersection(C[i],C[j],sol); sol.push_back(0); sol.push_back(PI*2); sort(sol.begin(),sol.end()); for(int j=0;j<sol.size();j++) { // cout<<sol[j]<<endl; double mid=(sol[j]+sol[j+1])/2.0; for(int d=-1;d<=1;d+=2) { double r2=C[i].r-d*eps; //cout<<r2<<endl; point a(C[i].o.x+cos(mid)*r2,C[i].o.y+sin(mid)*r2); int t=topmost(a); if(t>=0) ret.insert(t); } } } cout<<ret.size()<<endl; } return 0;}
本人比较弱,看到题之后没思路,找题解,题解解释如下:
平面上给n个圆盘,有先后顺序的叠放在一起,求最后有多少个是可见的。
只要没有被完全遮住就是可见的。
首先,要是我们能枚举所有的点,找到覆盖这个点的圆盘中,最上面的,那么这个圆一定时可见的,否则被遮住,那么它不是最上面的。
好了,那么只要给一个点,找到topmost那务必是符合要求的,
现在就想怎么找到所有符合要求的圆盘。
对一个可见的圆盘,它必定至少有一部分是可见的,这一部分,必定是由圆弧组成,对于这块圆弧组成的区域,再没有任何圆盘去覆盖,我们取区域内的一个点的topmost一定能找到它。1那我们就取弧的中点,偏向一点2怎么取到内部? r+-eps,不是加就是减,总之取多了没关系,没漏掉就好。(微小扰动没关系--+-eps一定还在内部)。
然后是,样例的点都精确到e-11了,eps显然要提高。
看了题解后,自己敲了一份代码,发现不对,DBUG了好久发现竟然是调用一个函数时忘记加括号了,由此来看,敲程序一定要认真,一点小错误都会导致满盘皆输。贴上我的代码:
0 0
- LA 2572 圆盘的相互覆盖问题,圆弧极角排序,中点代替圆弧,轻微扰动的影响判断
- 生成圆弧的中点算法
- 使用python 在已知圆弧两个端点和中点坐标 计算圆弧的圆心坐标
- 圆盘覆盖,计算几何(圆盘问题,LA 2572)
- 判断线段与圆弧的交点
- iOS中Quartz2D的画圆弧问题
- Android画圆弧的角度问题
- 圆弧并 uva 10969 && LA 2572
- iOS view的指定角设置圆弧
- view的指定角设置圆弧
- 多边形裁剪圆的实现细节之求出一段圆弧的中点
- UIBezierPath画圆弧的记录
- UIBezierPath画圆弧的记录
- UIBezierPath画圆弧的记录
- UIBezierPath画圆弧的记录
- 点到圆弧的距离
- UIBezierPath画圆弧的记录
- 圆弧的动画效果实现
- mysql主从复制要点
- 在django中创建多个数据库
- Python之游戏Pong的简单实现
- C++基础知识
- Swift 开源项目精选
- LA 2572 圆盘的相互覆盖问题,圆弧极角排序,中点代替圆弧,轻微扰动的影响判断
- 解决Error1935
- 刚旭电话录音系统
- 插入排序分析及优化
- 黑马程序员------java高新技术(反射)
- 【水题】【NOIP】【cogs1054】分数线划定
- UIButton文字颜色无法修改的解决方法和知识拓展
- Android开发的几个关键指标以及如何优化
- 博客搬家至个人博客