转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud

Viva Confetti
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 881   Accepted: 361

Description

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.


x1 y1 r1 
x2 y2 r2 
... 
xn yn rn

The first line in a configuration is the number of discs in the configuration (a positive integer not more than 100), followed by one line 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 +/- 5 x 10^(-13). That is, it is guaranteed that variations of less than +/- 5 x 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, x1 y1 r1 being the bottom one and xn yn rn 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

3
0 0 0.5
-0.9 0 1.00000000001
0.9 0 1.00000000001
5
0 1 0.5
1 1 1.00000000001
0 2 1.00000000001
-1 1 1.00000000001
0 -0.00001 1.00000000001
5
0 1 0.5
1 1 1.00000000001
0 2 1.00000000001
-1 1 1.00000000001
0 0 1.00000000001
2
0 0 1.0000001
0 0 1
2
0 0 1
0.00000001 0 1
0

Sample Output

3
5
4
2
2

依照顺序摆放下n个圆,问最终有多少个圆是可见的。

想了好久,然后问了队友shu_mj,想了好一会才想通。

首先,可见部分的一部分的边界一定是圆弧。于是,我们可以先求出所有的圆相交划分的一小段一小段的圆弧,然后把这些小段圆弧的中点稍微往圆内移动一点以及往外移动一点。然后从后放的圆开始判断,最先出现在哪个圆中,那么这个圆就是可见的。

 /**
* code generated by JHelper
* More info: https://github.com/AlexeyDmitriev/JHelper
* @author xyiyy @https://github.com/xyiyy
*/ #include <iostream>
#include <fstream> //#####################
//Author:fraud
//Blog: http://www.cnblogs.com/fraud/
//#####################
//#pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include <sstream>
#include <ios>
#include <iomanip>
#include <functional>
#include <algorithm>
#include <vector>
#include <string>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <climits>
#include <cctype> using namespace std;
#define pb(X) push_back(X)
#define rep(X, N) for(int X=0;X<N;X++)
#define ALL(X) (X).begin(),(X).end() //
// Created by xyiyy on 2015/8/10.
// #ifndef JHELPER_EXAMPLE_PROJECT_P_HPP
#define JHELPER_EXAMPLE_PROJECT_P_HPP const double EPS = 4e-; double add(double a, double b) {
if (fabs(a + b) < EPS * (fabs(a) + fabs(b)))return ;
return a + b;
} class P {
public:
double x, y; P() { } P(double x, double y) : x(x), y(y) { } P operator+(const P &p) {
return P(add(x, p.x), add(y, p.y));
} P operator-(const P &p) {
return P(add(x, -p.x), add(y, -p.y));
} P operator*(const double &d) {
return P(x * d, y * d);
} P operator/(const double &d) {
return P(x / d, y / d);
} double dot(P p) {
return add(x * p.x, y * p.y);
} double abs() {
return sqrt(abs2());
} double abs2() {
return dot(*this);
} }; //求两圆的极角 以p为中心
double polarangle(P p, P q) {
return atan2(q.y - p.y, q.x - p.x);
} #endif //JHELPER_EXAMPLE_PROJECT_P_HPP const long double PI2 = * acos(-1.0); long double update(double x) {
while (x < 0.0)x += PI2;
while (x >= PI2)x -= PI2;
return x;
} class poj1418 {
public:
void solve(std::istream &in, std::ostream &out) {
int n;
P t;
while (in >> n && n) {
vector<P> ps;
vector<double> rs;
vector<bool> cansee(n, );
rep(i, n) {
double x, y, r;
in >> x >> y >> r;
ps.pb(P(x, y));
rs.pb(r);
}
rep(i, n) {
vector<double> pp;
pp.pb(0.0);
pp.pb(PI2);
rep(j, n) {
double a = rs[i];
double d = (ps[i] - ps[j]).abs();
double b = rs[j];
if (a + b < d || a + d < b || b + d < a)continue;
double theta = acos((a * a + d * d - b * b) / ( * a * d));
double alpha = polarangle(ps[i], ps[j]);
pp.pb(update(alpha - theta));
pp.pb(update(alpha + theta));
}
sort(ALL(pp));
rep(j, pp.size() - ) {
double theta = (pp[j] + pp[j + ]) / ;
for (int k = -; k <= ; k += ) {
t.x = ps[i].x + (rs[i] + k * EPS) * cos(theta);
t.y = ps[i].y + (rs[i] + k * EPS) * sin(theta);
int gao = n - ;
for (; gao >= ; gao--) {
if ((ps[gao] - t).abs() < rs[gao])break;
}
if (gao != -)cansee[gao] = ;
}
}
}
out << count(ALL(cansee), ) << endl;
}
}
}; int main() {
std::ios::sync_with_stdio(false);
std::cin.tie();
poj1418 solver;
std::istream &in(std::cin);
std::ostream &out(std::cout);
solver.solve(in, out);
return ;
}

代码君

poj1418 Viva Confetti 判断圆是否可见的更多相关文章

  1. poj 1418 Viva Confetti

    Viva Confetti Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 1025   Accepted: 422 Desc ...

  2. ZOJ 1696 Viva Confetti 计算几何

    计算几何:按顺序给n个圆覆盖.问最后能够有几个圆被看见.. . 对每一个圆求和其它圆的交点,每两个交点之间就是可能被看到的圆弧,取圆弧的中点,往外扩展一点或者往里缩一点,从上往下推断有没有圆能够盖住这 ...

  3. uva 1308 - Viva Confetti

    这个题目的方法是将圆盘分成一个个圆环,然后判断这些圆环是否被上面的圆覆盖: 如果这个圆的圆周上的圆弧都被上面的覆盖,暂时把它标记为不可见: 然后如果他的头上有个圆,他有个圆弧可见,那么他自己本身可见, ...

  4. A Round Peg in a Ground Hole - POJ 1584 (判断凸多边形&判断点在多边形内&判断圆在多边形内)

    题目大意:首先给一个圆的半径和圆心,然后给一个多边形的所有点(多边形按照顺时针或者逆时针给的),求,这个多边形是否是凸多边形,如果是凸多边形在判断这个圆是否在这个凸多边形内.   分析:判断凸多边形可 ...

  5. 判断圆和矩形是否相交C - Rectangle and Circle

    Description Given a rectangle and a circle in the coordinate system(two edges of the rectangle are p ...

  6. HDU 1221 Rectangle and Circle(判断圆和矩形是不是相交)

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1221 Rectangle and Circle Time Limit: 2000/1000 MS (J ...

  7. POJ1584 A Round Peg in a Ground Hole 凸包判断 圆和凸包的关系

    POJ1584 题意:给定n条边首尾相连对应的n个点 判断构成的图形是不是凸多边形 然后给一个圆 判断圆是否完全在凸包内(相切也算) 思路:首先运用叉积判断凸多边形 相邻三条边叉积符号相异则必有凹陷 ...

  8. UVaLive2572 poj1418 UVa1308 Viva Confetti

    一次放下n个圆 问最终可见的圆的数量 应该是比较经典的问题吧 考虑一个圆与其他每个圆的交点O(n)个 将其割成了O(n)条弧 那么看每条弧的中点 分别向内向外调动eps这个点 则最上面的覆盖这个点的圆 ...

  9. POJ 1584 /// 判断圆(点)在多边形内 判断凸包

    题目大意: 给定n,n边形 给定圆钉的 半径r 和圆心(x,y) 接下来n行是n边形的n个顶点(顺时针或逆时针给出) 判断n边形是否为凸包 若不是输出 HOLE IS ILL-FORMED 判断圆心和 ...

随机推荐

  1. C/C++堆栈指引(转)

    C/C++堆栈指引 Binhua Liu 前言 我们经常会讨论这样的问题:什么时候数据存储在堆栈(Stack)中,什么时候数据存储在堆(Heap)中.我们知道,局部变量是存储在堆栈中的:debug时, ...

  2. java 批量插入10万条数据

    for (int i = 0; i < 100000; i++) { dbHelper.insert("INSERT aaa(name) Values ('1')"); } ...

  3. QT 让窗口(或控件)居中

    代码如下: XXX::XXX(QWidget *parent /* = 0 */) { .................. //注意,resize一定要放在这段代码的前面 resize(300, 3 ...

  4. VCRedist.exe静默安装方法(转)

    INNO setup 制作安装包  的时候,发布VC++运行时 [Run]Filename: {app}vcredist_x86.exe; Parameters: /q; WorkingDir: {t ...

  5. 关于mysql的自增

    http://my.oschina.net/zimingforever/blog/136599 http://flandycheng.blog.51cto.com/855176/280224 http ...

  6. COJ 0999 WZJ的数据结构(负一)

    WZJ的数据结构(负一) 难度级别:D: 运行时间限制:1000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 输入N个模板串Pi和文本串T,输出每个模板串Pi在T ...

  7. 【转】android应用开发全程实录-你有多熟悉listview?---不错

    原文网址:http://www.cnblogs.com/noTice520/archive/2011/12/05/2276379.html 今天给大家带来<android应用开发全程实录> ...

  8. delphi7调用webservice Java 传入参数为空

    在delphi7中,new-webservices-wsdl importer中输入wsdl地址,会自动生成wsdl单元代码.在调用时,传入参数到服务器端时为空了. 网上说缺少 InvRegistry ...

  9. cf498C Array and Operations

    C. Array and Operations time limit per test 1 second memory limit per test 256 megabytes input stand ...

  10. Android中的测试类配置AndroidManifest.xml

    测试类至于要把一个类继承ActivityTestCase即可至于方法,根据需要自己建立方法:之后必须配置AnroidMainfest.xml文件 配置AndroidManifest.xml文件 1) ...