LA2572 UVA1308
来源:互联网 发布:社交网络肖恩帕克最后 编辑:程序博客网 时间:2024/05/21 22:36
Do you know confetti? They are small discs of colored paper, and people throw them around during parties or festivals. Since people throw lots of confetti, they may end up stacked one on another, so there may be hidden ones underneath.
A handful of various sized confetti have been dropped on a table. Given their positions and sizes, can you tell us how many of them you can see?
The following figure represents the disc configuration for the first sample input, where the bottom disc is still visible.
Input
The input is composed of a number of configurations of the following form.
The first line in a configuration is the number of discs in the configuration (a positive integer not more than 100), followed by one Ine descriptions of each disc: coordinates of its center and radius, expressed as real numbers in decimal notation, with up to 12 digits after the decimal point. The imprecision margin is 5x 10-13 . That is, it is guaranteed that variations of less than5x 10-13 on input values do not change which discs are visible. Coordinates of all points contained in discs are between -10 and 10.
Confetti are listed in their stacking order, x1y1 r1 being the bottom one andxn ynrn the top one. You are observing from the top.
The end of the input is marked by a zero on a single line.
Output
For each configuration you should output the number of visible confetti on a single line.
Sample Input
30 0 0.5-0.9 0 1.000000000010.9 0 1.0000000000150 1 0.51 1 1.000000000010 2 1.00000000001-1 1 1.000000000010 -0.00001 1.0000000000150 1 0.51 1 1.000000000010 2 1.00000000001-1 1 1.000000000010 0 1.0000000000120 0 1.00000010 0 120 0 10.00000001 0 10
Sample Output
35422
// LA2572/UVa1308 Viva Confetti// Rujia Liu#include<cmath>#include<algorithm>#include<cstring>#include<iostream>#include<vector>using namespace std;const double eps = 5 * 1e-13;int dcmp(double x) { if(fabs(x) < eps) return 0; else return x < 0 ? -1 : 1;}const double PI = acos(-1);const double TWO_PI = PI * 2;double NormalizeAngle(double rad, double center = PI) { return rad - TWO_PI * floor((rad + PI - center) / TWO_PI);}struct Point { double x, y; Point(double x=0, double y=0):x(x),y(y) { }};typedef Point Vector;Vector operator + (Vector A, Vector 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 * (Vector A, double p) { return Vector(A.x*p, A.y*p); }Vector operator / (Vector A, double p) { return Vector(A.x/p, A.y/p); }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);}// 交点相对于圆1的极角保存在rad中void getCircleCircleIntersection(Point c1, double r1, Point c2, double r2, vector<double>& rad) { double d = Length(c1 - c2); if(dcmp(d) == 0) return; // 不管是内含还是重合,都不相交 if(dcmp(r1 + r2 - d) < 0) return; if(dcmp(fabs(r1-r2) - d) > 0) return; double a = angle(c2 - c1); double da = acos((r1*r1 + d*d - r2*r2) / (2*r1*d)); rad.push_back(NormalizeAngle(a-da)); rad.push_back(NormalizeAngle(a+da));}const int maxn = 100 + 5;int n;Point center[maxn];double radius[maxn];bool vis[maxn];// 覆盖点p的最上层的圆int topmost(Point p) { for(int i = n-1; i >= 0; i--)//自顶向底 枚举每个圆看能不能覆盖这个点! if(Length(center[i]-p) < radius[i]) return i; return -1;}int main() { while(cin >> n) { if(!n) break; for(int i = 0; i < n; i++) { double x, y, r; cin >> x >> y >> r; center[i] = Point(x, y); radius[i] = r; } memset(vis, 0, sizeof(vis)); for(int i = 0; i < n; i++) { // 自底向上 枚举每个圆。 // 考虑圆i被切割成的各个圆弧。把圆周当做区间来处理,起点是0,终点是2PI vector<double> rad; rad.push_back(0); rad.push_back(PI*2);/**对于那些和其他圆没有交点的圆,那么这段小圆弧就是整个圆周**/ for(int j = 0; j < n; j++) getCircleCircleIntersection(center[i], radius[i], center[j], radius[j], rad);//求出每个圆与 该圆i 的交点。 sort(rad.begin(), rad.end());//按极角排序 for(int j = 0; j < rad.size(); j++) { //枚举每个小圆弧 double mid = (rad[j] + rad[j+1]) / 2.0; // 圆弧中点相对于圆i圆心的极角 for(int side = -1; side <= 1; side += 2) { double r2 = radius[i] - side*eps; // 往里面或者外面稍微一动一点点 int t = topmost(Point(center[i].x + cos(mid)*r2, center[i].y + sin(mid)*r2));//看这个稍稍移动的点 在哪个圆上。 if(t >= 0) vis[t] = true;//标记这个点在的小圆弧为真。 } } } int ans = 0; for(int i = 0; i < n; i++) if(vis[i]) ans++; cout << ans << "\n"; } return 0;}
- LA2572 UVA1308
- uva1308 Viva Confetti
- LA2572 Viva Confetti 计算几何
- 3dMax导出fbx三维模型到Unity3D中
- 眼睛眯起,就像是想要找个地方睡觉一样,令人极端不
- HTML标签fieldset
- 问题解决——使用串口调试助手发送控制字符 协议指令 <ESC>!?
- cocos2dx用python创建项目
- LA2572 UVA1308
- Json与bean互转的例子
- 使用亚马逊云服务所跳过的坑
- 【Unity3D自学记录】MAC&Windows跨平台解析Excel
- CSDN之HelloWorld!
- C++ primer(第五版) 练习 3.32 个人code
- string在C和C++中的用法
- swift 小记录
- 关于mac和PC连接多个显示器共享鼠标键盘,粘贴板的解决方案。