uva 1308 - Viva Confetti
这个题目的方法是将圆盘分成一个个圆环,然后判断这些圆环是否被上面的圆覆盖;
如果这个圆的圆周上的圆弧都被上面的覆盖,暂时把它标记为不可见;
然后如果他的头上有个圆,他有个圆弧可见,那么他自己本身可见,并且可以把这条圆弧下面的第一个圆重新标记为可见;
另外,圆弧可见还是不可见利用它的中点来进行判断;
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector> using namespace std; const int maxn = + ;
const double eps = 1e-; //别开太大,样例数据就到达1e-11级别
const double pi = acos(-); int dcmp(double x)
{
return fabs(x) < eps ? : (x > ? : -);
} struct Point
{
double x;
double y; Point(double x = , double y = ):x(x), y(y) {} bool operator < (const Point& e) const
{
return dcmp(x - e.x) < || (dcmp(x - e.x) == && dcmp(y - e.y) < );
} bool operator == (const Point& e) const
{
return dcmp(x - e.x) == && dcmp(y - e.y) == ;
} int read()
{
return scanf("%lf%lf", &x, &y);
}
}; typedef Point Vector; Vector operator + (Point A, Point B)
{
return Vector(A.x + B.x, A.y + B.y);
} Vector operator - (Point A, Point B)
{
return Vector(A.x - B.x, A.y - B.y);
} Vector operator * (Point A, double p)
{
return Vector(A.x * p, A.y * p);
} Vector operator / (Point A, double p)
{
return Vector(A.x / p, A.y / p);
} struct Circle
{
Point c;
double r; Circle() {}
Circle(Point c, double r):c(c), r(r) {} int read()
{
return scanf("%lf%lf%lf", &c.x, &c.y, &r);
} Point point(double a)
{
return Point(c.x + r * cos(a), c.y + r * sin(a));
}
}; double Dot(Vector A, Vector B)
{
return A.x * B.x + A.y * B.y;
} double Length(Vector A)
{
return sqrt(Dot(A, A));
} double angle(Vector v) //求向量的极角
{
return atan2(v.y, v.x);
} bool PointInCircle(Point p, Circle C) //判断点是否在圆内
{
double dist = Length(p - C.c);
if(dcmp(dist - C.r) > ) return ; //这里我选择点在圆边上不算在圆内
else return ;
} bool CircleInCircle(Circle A, Circle B) //判断圆在圆内
{
double cdist = Length(A.c - B.c);
double rdiff = B.r - A.r;
if(dcmp(A.r - B.r) <= && dcmp(cdist - rdiff) <= ) return ; //包括重合,内切和内含的情况
return ;
} int n;
Circle C[maxn];
bool vis[maxn];
vector<double> pointAng[maxn]; int GetCircleCircleIntersection(int c1, int c2) //求圆与圆的交点
{
Circle C1 = C[c1];
Circle C2 = C[c2];
double d = Length(C1.c - C2.c);
if(dcmp(d) == )
{
if(dcmp(C1.r - C2.r) == ) return -; //两圆重合
return ; //同心圆但不重合
}
if(dcmp(C1.r + C2.r - d) < ) return ; //外离
if(dcmp(fabs(C1.r - C2.r) - d) > ) return ; //内含
double a = angle(C2.c - C1.c);
double da = acos((C1.r * C1.r + d * d - C2.r * C2.r) / ( * C1.r * d));
Point p1 = C1.point(a + da);
Point p2 = C1.point(a - da);
if(p1 == p2) return ; //相切
pointAng[c1].push_back(a + da); //相切的点不处理,只要相交的
pointAng[c1].push_back(a - da);
return ;
} void init()
{
for(int i = ; i < n; i++) pointAng[i].clear();
memset(vis, , sizeof(vis));
} void read()
{
for(int i = ; i < n; i++) C[i].read();
} void solve()
{
for(int i = ; i < n; i++) //圆两两相交,得各圆交点集合
for(int j = ; j < n; j++) if(i != j)
GetCircleCircleIntersection(i, j);
for(int i = ; i < n; i++)
{
sort(pointAng[i].begin(), pointAng[i].end()); //各圆交点按极角排序
vector<double>::iterator iter = unique(pointAng[i].begin(), pointAng[i].end()); //去重,可减少运行时间,不去重也能AC
pointAng[i].resize(distance(pointAng[i].begin(), iter));
}
for(int i = ; i < n; i++) //判断第i个圆上的弧
{
int sz = pointAng[i].size();
if(!sz) //此圆不与其他圆相交
{
bool ok = ;
for(int k = i+; k < n; k++) if(CircleInCircle(C[i], C[k])) //判上面是否有圆把它覆盖掉
{
ok = ;
break;
}
if(ok) vis[i] = ;
}
else
{
pointAng[i].push_back(pointAng[i][]);
for(int j = ; j < sz; j++) //第i个圆上的第j条弧
{
bool ok = ;
Point pm = C[i].point((pointAng[i][j] + pointAng[i][j+]) / ); //取弧的中点
for(int k = i+; k < n; k++) if(PointInCircle(pm, C[k]))
{
ok = ;
break;
}
if(ok)
{
vis[i] = ;
for(int u = i-; u >= ; u--)if(PointInCircle(pm, C[u])) //把这段圆弧下的圆设为可见
{
vis[u] = ;
break;
}
}
}
}
}
int ret = ;
for(int i = ; i < n; i++) if(vis[i]) ret++;
printf("%d\n", ret);
} int main()
{
while(scanf("%d", &n) == && n)
{
init();
read();
solve();
}
return ;
}
uva 1308 - Viva Confetti的更多相关文章
- uva 2572 Viva Confetti
思路: 小圆面是由小圆弧围成.那么找出每条小圆弧,如果小圆弧,在小圆弧中点上下左右进行微小位移的所得的点一定在一个小圆面内. 找到最后覆盖这个小点的圆一定是可见的. 圆上的点按照相邻依次排序的关键量为 ...
- poj1418 Viva Confetti 判断圆是否可见
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud Viva Confetti Time Limit: 1000MS Memory ...
- poj 1418 Viva Confetti
Viva Confetti Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 1025 Accepted: 422 Desc ...
- ZOJ 1696 Viva Confetti 计算几何
计算几何:按顺序给n个圆覆盖.问最后能够有几个圆被看见.. . 对每一个圆求和其它圆的交点,每两个交点之间就是可能被看到的圆弧,取圆弧的中点,往外扩展一点或者往里缩一点,从上往下推断有没有圆能够盖住这 ...
- UVaLive2572 poj1418 UVa1308 Viva Confetti
一次放下n个圆 问最终可见的圆的数量 应该是比较经典的问题吧 考虑一个圆与其他每个圆的交点O(n)个 将其割成了O(n)条弧 那么看每条弧的中点 分别向内向外调动eps这个点 则最上面的覆盖这个点的圆 ...
- LA2572 Viva Confetti
题意 PDF 分析 两两圆求交点,对每个圆弧按半径抖动. 时间复杂度\(O(T n^2)\) 代码 #include<iostream> #include<cstdio> #i ...
- [GodLove]Wine93 Tarining Round #9
比赛链接: http://vjudge.net/contest/view.action?cid=48069#overview 题目来源: lrj训练指南---二维几何计算 ID Title Pro ...
- POJ 1418 基本操作和圆 离散弧
Viva Confetti Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 761 Accepted: 319 Descr ...
- uva 1354 Mobile Computing ——yhx
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAABGcAAANuCAYAAAC7f2QuAAAgAElEQVR4nOy9XUhjWbo3vu72RRgkF5
随机推荐
- Java基础知识强化之IO流笔记42:IO流总结(图解)
1. IO流总结(图解)
- 转:oracle ebs po模块一揽子采购协议小结
转自:http://yedward.net/?id=193 oracle ebs po模块一揽子采购协议小结 本文总结oracle ebs采购订单(po)模块一揽子采购协议的相关知识,总结如下: 1. ...
- 堆排序算法(C#实现)
在软件设计相关领域,“堆(Heap)”的概念主要涉及到两个方面: 一种是数据结构,逻辑上是一颗完全二叉树,存储上是一个数组对象(二叉堆). 另一种是垃圾收集存储区,是软件系统可以编程的内存区域. 本文 ...
- web服务器压力测试工具
http_load 是运行在linux操作系统上的命令行测试工具, 用来对网站做压力测试. 下载地址:http://www.acme.com/software/http_load/http_load- ...
- c#中的重写方法与隐藏方
1.父类中有方法a,添加virtua修饰符可声明为虚方法,在子类中可以用override声明后重写方法a. 2.父类中有方法a,在子类中可以有new修饰符声明后隐藏父类方法. 子类重写方法后,对于子类 ...
- vi 或 vim 常用命令(简单够用了)
1.vi filename :打开或新建文件,并将光标置于第一行首 2.按下i键:编辑或插入数据3.按下shit+: ->表示可以进行命令输入 4.q! ->表示不保存退出.5.w -&g ...
- ERROR 1045 (28000): Access denied for user 'root'@'localhost'
# /etc/init.d/mysql stop# mysqld_safe --user=mysql --skip-grant-tables --skip-networking &# mysq ...
- IOS 学习日志 2015-3-16
Objective--C 一 关键字 self 相当于java中的this,但是又有不同 它即可一代替对象,也可以代替类, 也就是说它既可以用在静态方法中又可以用在动态方法中. super 相当于父类 ...
- leetcode problem (2-4)
Problem 2 --- Add Two Numbers 简单的模拟题. Problem 3 --- Longest Substring Without Repeating Characters 题 ...
- SQLite学习第01天:参考资料
今天开始学习数据库相关的知识,由于本人从事的是嵌入式软件开发方向,所以在数据库的选择时就果断选择了SQLite,在网上搜索了一下相关的资料并且配置好了环境.首先,想要对SQLite有一个基本的了解还是 ...