poj1418 Viva Confetti 判断圆是否可见
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 881 | Accepted: 361 |
Description
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
n
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
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 判断圆是否可见的更多相关文章
- poj 1418 Viva Confetti
Viva Confetti Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 1025 Accepted: 422 Desc ...
- ZOJ 1696 Viva Confetti 计算几何
计算几何:按顺序给n个圆覆盖.问最后能够有几个圆被看见.. . 对每一个圆求和其它圆的交点,每两个交点之间就是可能被看到的圆弧,取圆弧的中点,往外扩展一点或者往里缩一点,从上往下推断有没有圆能够盖住这 ...
- uva 1308 - Viva Confetti
这个题目的方法是将圆盘分成一个个圆环,然后判断这些圆环是否被上面的圆覆盖: 如果这个圆的圆周上的圆弧都被上面的覆盖,暂时把它标记为不可见: 然后如果他的头上有个圆,他有个圆弧可见,那么他自己本身可见, ...
- A Round Peg in a Ground Hole - POJ 1584 (判断凸多边形&判断点在多边形内&判断圆在多边形内)
题目大意:首先给一个圆的半径和圆心,然后给一个多边形的所有点(多边形按照顺时针或者逆时针给的),求,这个多边形是否是凸多边形,如果是凸多边形在判断这个圆是否在这个凸多边形内. 分析:判断凸多边形可 ...
- 判断圆和矩形是否相交C - Rectangle and Circle
Description Given a rectangle and a circle in the coordinate system(two edges of the rectangle are p ...
- HDU 1221 Rectangle and Circle(判断圆和矩形是不是相交)
传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1221 Rectangle and Circle Time Limit: 2000/1000 MS (J ...
- POJ1584 A Round Peg in a Ground Hole 凸包判断 圆和凸包的关系
POJ1584 题意:给定n条边首尾相连对应的n个点 判断构成的图形是不是凸多边形 然后给一个圆 判断圆是否完全在凸包内(相切也算) 思路:首先运用叉积判断凸多边形 相邻三条边叉积符号相异则必有凹陷 ...
- UVaLive2572 poj1418 UVa1308 Viva Confetti
一次放下n个圆 问最终可见的圆的数量 应该是比较经典的问题吧 考虑一个圆与其他每个圆的交点O(n)个 将其割成了O(n)条弧 那么看每条弧的中点 分别向内向外调动eps这个点 则最上面的覆盖这个点的圆 ...
- POJ 1584 /// 判断圆(点)在多边形内 判断凸包
题目大意: 给定n,n边形 给定圆钉的 半径r 和圆心(x,y) 接下来n行是n边形的n个顶点(顺时针或逆时针给出) 判断n边形是否为凸包 若不是输出 HOLE IS ILL-FORMED 判断圆心和 ...
随机推荐
- C#泛型理解(转)
[译]C# 理解泛型 PDF 浏览:http://www.tracefact.net/document/generics-in-csharp.pdf源码下载:http://www.tracefact ...
- IE中对于stylesheet的个数限制
对于IE6-9: 1.样式规则最多只能有4095个,多于这个数目的会被忽略: 2.样式表(通过@import, <link> 或 <style>)最多可以有31个(总和),多于 ...
- 用PYTHON实现将电脑里的所有文件按大小排序,便于清理
嘿嘿,慢慢找到写代码的感觉了. 这个小程序涉及的东东还是很多的,数据结构的设计,错误的处理,快速字典排序,文件数值调整.... import os,os.path import glob SUFFIX ...
- 向PE文件中添加一个Section
背景 之前说过直接向类HelloWorld.exe的可执行文件添加一个MessageBox弹窗, 但有时候, 需要添加的内容太多了, 因为数据与代码一起插入, 以至于可执行文件本身没有足够的空闲空间存 ...
- MySQL 遇到的问题:在服务里找不到自己的 MySQL,以及在命令行窗口中运行服务出现的问题。
1.用数据库的时候在服务里找不到自己的 MySQL ,于是就想用命令行窗口去运行. ①.在开始里,键入 cmd ,打开命令行窗口. ②.输入:mysql -u root -p 回车,这时会提示请输入密 ...
- Adobe Photoshop CC 2015安装激活
分享一下Adobe Photoshop CC 2015 安装激活步骤 工具/原料 xf-adobecc2015.exe Adobe Photoshop CC 2015官方原版 方法/步骤 1 ...
- css3 渐变linear-gradient
background: -moz-linear-gradient(top, #FC641C, #FC761C); 参数:其共有三个参数,第一个参数表示线性渐变的方向,top 是从上到下.left 是从 ...
- (转)鸟哥SHELL入门材料
http://blog.chinaunix.net/space.php?uid=9809038&do=blog&cuid=62903 经典入门材料! 学习 Shell Scripts ...
- SQL 查询某字段id为空(不为空)
1 sql 查询某字段id为空 select * from 表名 where id is null ; 2 sql 查询某字段id不为空 select * from 表名 wher ...
- android 几种发送短信的方法
android中发送短信很简单, 首先要在Mainfest.xml中加入所需要的权限: ? 1 2 3 <uses-permission android:name="android.p ...