题意:

把n个圆盘依次放到桌面上,按照放置的先后顺序给出这n个圆盘的圆心和半径,输出有多少个圆盘可见(即未被全部覆盖)。

分析:

题中说对输入数据进行微小扰动后答案不变。

所露出的部分都是由若干小圆弧组成的。因此求出每个圆与其他圆相交的小圆弧,取圆弧的终点,分别向里和向外移动一个很小的距离的到P'。标记包含P'的最上面的那个圆为可见。

 //#define LOCAL
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std; const int maxn = ;
const double PI = acos(-1.0);
const double Two_PI = PI * ;
const double eps = * 1e-;
int n;
double radius[maxn];
bool vis[maxn]; int dcmp(double x)
{
if(fabs(x) < eps) return ;
else return x < ? - : ;
} struct Point
{
double x, y;
Point(double x=, double y=):x(x), y(y) {}
};
typedef Point Vector;
Point operator + (Point A, Point B) { return Point(A.x+B.x, A.y+B.y); }
Point operator - (Point A, Point B) { return Point(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); }
Point center[maxn]; 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); }
double NormalizeAngle(double rad)
{//将所求角度化到0到2π之间
return rad - Two_PI*(floor(rad/Two_PI));
} void getCCIntersection(Point c1, double r1, Point c2, double r2, vector<double>& rad)
{
double d = Length(c1 - c2);
if(dcmp(d) == ) return;
if(dcmp(d-r1-r2) > ) return;
if(dcmp(d-fabs(r1-r2)) < ) return; double a = angle(c2-c1);
double ag = acos((r1*r1+d*d-r2*r2)/(*r1*d));
rad.push_back(NormalizeAngle(a + ag));
rad.push_back(NormalizeAngle(a - ag));
} int topmost(Point P)
{
for(int i = n-; i >= ; --i)
if(Length(P-center[i]) < radius[i]) return i;
return -;
} int main(void)
{
#ifdef LOCAL
freopen("2572in.txt", "r", stdin);
#endif while(scanf("%d", &n) == && n)
{
for(int i = ; i < n; ++i)
scanf("%lf%lf%lf", &center[i].x, &center[i].y, &radius[i]);
memset(vis, , sizeof(vis)); for(int i = ; i < n; ++i)
{
vector<double> rad;
rad.push_back(0.0);
rad.push_back(Two_PI);
for(int j = ; j < n && j != i; ++j)
getCCIntersection(center[i], radius[i], center[j], radius[j], rad);
sort(rad.begin(), rad.end()); for(int j = ; j < rad.size() - ; ++j)
{
double mid = (rad[j] + rad[j+]) / 2.0;
for(int side = -; side <= ; side += )
{
double r = radius[i] + side*eps;
int t = topmost(Point(center[i].x+r*cos(mid), center[i].y+r*sin(mid)));
if(t >= ) vis[t] = true;
}
}
}
int ans = ;
for(int i = ; i < n; ++i) if(vis[i]) ++ans;
printf("%d\n", ans);
} return ;
}

代码君

LA 2572 (求可见圆盘的数量) Kanazawa的更多相关文章

  1. 求拓扑排序的数量,例题 topcoder srm 654 div2 500

    周赛时遇到的一道比较有意思的题目: Problem Statement      There are N rooms in Maki's new house. The rooms are number ...

  2. Gym 100342J Triatrip (求三元环的数量) (bitset优化)

    <题目链接> 题目大意:用用邻接矩阵表示一个有向图,现在让你求其中三元环的数量. 解题分析:先预处理得到所有能够直接到达每个点的集合$arrive[N]$和所有能够由当前点到达的集合$to ...

  3. Gym - 100342J:Triatrip(Bitset加速求三元环的数量)

    题意:求有向图里面有多少个三元环. 思路:枚举起点A,遍历A可以到的B,然后求C的数量,C的数量位B可以到是地方X集合,和可以到A的地方Y集合的交集(X&Y). B点可以枚举,也可以遍历.(两 ...

  4. 分别利用并查集,DFS和BFS方法求联通块的数量

    联通块是指给定n个点,输入a,b(1<=a,b<=n),然后将a,b连接,凡是连接在一起的所有数就是一个联通块: 题意:第一行输入n,m,分别表示有n个数,有输入m对连接点,以下将要输入m ...

  5. SPOJ Distanct Substrings(求不同子串的数量)

    Given a string, we need to find the total number of its distinct substrings. Input T- number of test ...

  6. poj3376 KMP+字典树求回文串数量(n*n)

    Finding Palindromes Time Limit: 10000MS   Memory Limit: 262144K Total Submissions: 4043   Accepted: ...

  7. Codeforces Gym 100342J Problem J. Triatrip 求三元环的数量 bitset

    Problem J. Triatrip Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100342/at ...

  8. Codeforces Gym 100342J Problem J. Triatrip bitset 求三元环的数量

    Problem J. TriatripTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100342/att ...

  9. hdu2852--KiKi&#39;s K-Number(段树,求第一k的数量)

    KiKi's K-Number Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

随机推荐

  1. Mysql几种索引类型的区别及适用情况

    如大家所知道的,Mysql目前主要有以下几种索引类型:FULLTEXT,HASH,BTREE,RTREE. 那么,这几种索引有什么功能和性能上的不同呢? FULLTEXT 即为全文索引,目前只有MyI ...

  2. android 开启或者隐藏软键盘

    一. 隐藏软键盘方法一(注:此方法本人使用时发现isActivie()失效,建议还是用其他方法..): InputMethodManager imm = (InputMethodManager)get ...

  3. CoreLocation MKMapView 地图

    系统自带地图  框架: CoreLocation MapKit CLLocationManager --> 定位管理者  CLGeocoder --> 地理编码器 MKMapView -- ...

  4. asp.net 通过ajax方式调用webmethod方法使用自定义类传参及获取返回参数

    实体类    public class User    {        public int Id { get; set; }        public string Name { get; se ...

  5. MySQL之重设密码(忘记密码)讲解

    Windows下的实际操作如下: 1.关闭正在运行的MySQL. 2.打开DOS窗口,转到mysql\bin目录. 3.输入mysqld(或mysqld-nt) --skip-grant-tables ...

  6. PHP对XML添加节点之appendChild()方法讲解

    问题如下:<b > <c>test</c> </b>我要在b节点里面添加一个子节点比如说加一个d节点,要实现成<b > <c>t ...

  7. 在C#中调用另一个应用程序或命令行(.exe 带参数)<zz>

    在.net中使用system.diaglostics.Process可以用来调用另一个命令行或程序. using   System.Diagnostics;     如果是dos     Proces ...

  8. *[topcoder]TheMatrix

    http://community.topcoder.com/stat?c=problem_statement&pm=13035 矩阵棋盘的题,比较典型.可以定两条column夹住,然后上下扫, ...

  9. Spring的lazy-init详解

    1.Spring中lazy-init详解ApplicationContext实现的默认行为就是在启动服务器时将所有singleton bean提前进行实例化(也就是依赖注入).提前实例化意味着作为初始 ...

  10. VCL ActiveX 播放视频

    播放网络视频 string[] options = new string[] { ":sout=#duplicate{dst=display} :no-overlay" }; st ...