hdu 4197 Popping Balloons 环状区间选点
来源:互联网 发布:淘宝客服离线自动回复 编辑:程序博客网 时间:2024/05/18 01:11
题意:给出n个球的圆心坐标和半径大小,从原点扔飞镖,求最小飞镖数使刺破所有球。(飞镖是射线,球可以穿透,没有球包含原点)
解法:n个球对应n个角度区间,然后这是一个(-PI,PI]内的环状区间选点问题,要求选最少的点,使之覆盖所有区间。
利用2tan()求出圆心的辐角,然后区间的左右端点是圆心的辐角-+两切线夹角的半角(asin()可求,(0,PI/2])
环状问题,通常可以将n个物体变为2*n个进行处理。对所有n个区间左右端点+2PI得到n个新区间。
然后按照经典问题的解法,枚举起始区间,进行n次,每次按照区间右端点从小到大排序,之后贪心。
需要做一个特殊的处理就是,因为新区间很可能排在其它老区间前面(比如x的新区间x2右端点是 PI-1,而y区间右端点是PI-2 )
那么连续处理n个区间的时候,很可能处理了某个区间x和它对应的新区间x2,但是没有处理y区间,这是有问题的。
正确的做法是将ri值严格限制在(-PI,PI] 范围内,如果ri超过了,le、ri同时减2*PI,小于了同时加2*PI。
还有一种改进是将所有新区间排在老区间后面,然后再按照ri排序,这是有问题的,因为后面的贪心法配合的排序方
法一定是ri从小到大。
Popping Balloons
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 444 Accepted Submission(s): 151
Problem Description
John loves programming contests. There is just one problem: his team is not very good at programming. This usually doesn't bother him, but what does bother him is that everyone gets a balloon for every correct submission. John's team never gets any balloons, while other teams get one balloon after the other. This frustrates him, so John would like to see that all other teams have no balloons either.
This year he has a plan to achieve just that. John has hired a ninja to pop all balloons for him. At any time during the contest, he can call for the ninja to come down through a hole in the ceiling and pop all balloons by using his shurikens (ninja stars), before leaving through the hole in the ceiling again. Of course the ninja wants to use as few of his precious shurikens as possible. Therefore, John must write a program that computes how many shurikens are needed to pop all balloons. Because all balloons are usually at approximately the same height, he can model the problem as a 2-dimensional problem. He sets the location of the ninja (where he comes in) as the origin (0, 0) and uses circles to model the balloons. To be on the safe side, these circles can have different radii. Shurikens are assumed to be thrown from the origin and move in a straight line. Any circle/balloon crossed by this haline will be popped by this shuriken. The question then becomes: how many halines rooted at the origin are necessary to cross all circles?
Of course, as mentioned above, John is not a very good programmer, so he asks you to make this program for him. Can you help him out? You might get a balloon if you get it right...
This year he has a plan to achieve just that. John has hired a ninja to pop all balloons for him. At any time during the contest, he can call for the ninja to come down through a hole in the ceiling and pop all balloons by using his shurikens (ninja stars), before leaving through the hole in the ceiling again. Of course the ninja wants to use as few of his precious shurikens as possible. Therefore, John must write a program that computes how many shurikens are needed to pop all balloons. Because all balloons are usually at approximately the same height, he can model the problem as a 2-dimensional problem. He sets the location of the ninja (where he comes in) as the origin (0, 0) and uses circles to model the balloons. To be on the safe side, these circles can have different radii. Shurikens are assumed to be thrown from the origin and move in a straight line. Any circle/balloon crossed by this haline will be popped by this shuriken. The question then becomes: how many halines rooted at the origin are necessary to cross all circles?
Of course, as mentioned above, John is not a very good programmer, so he asks you to make this program for him. Can you help him out? You might get a balloon if you get it right...
Input
The first line of the input contains a single number: the number of test cases to follow. Each test case has the following format:
1.One line with a single integer n (0 <= n <= 1,000): the number of balloons.
2.n lines, each containing three integers xi,yi (-10^4 <= xi,yi <= 10^4), and ri (1 <= ri <= 10^4),describing the circle used to model the ith balloon, where (xi, yi) is the center of the circle and ri is the radius.
You can assume that two lines (rooted at the origin) that are tangent to two distinct circles make an angle of at least 10^-6 radians at the origin. Furthermore, the circles do not cross each other (but can touch) and do not contain the origin.
1.One line with a single integer n (0 <= n <= 1,000): the number of balloons.
2.n lines, each containing three integers xi,yi (-10^4 <= xi,yi <= 10^4), and ri (1 <= ri <= 10^4),describing the circle used to model the ith balloon, where (xi, yi) is the center of the circle and ri is the radius.
You can assume that two lines (rooted at the origin) that are tangent to two distinct circles make an angle of at least 10^-6 radians at the origin. Furthermore, the circles do not cross each other (but can touch) and do not contain the origin.
Output
For every test case in the input, the output should contain one integer on a single line: the minimum number of shurikens the ninja needs to pop all balloons.
Sample Input
2 5 2 0 15 0 20 3 2-4 0 20 -2 154 1 35 -5 30 -4 2-4 4 3-10 3 3
Sample Output
43HintNo balloons were harmed during the making of this problem.
Source
BAPC 2011
Recommend
lcy | We have carefully selected several similar problems for you: 4198 4199 4200 4202 4203
#include<cstdio>#include<string>#include<cstring>#include<iostream>#include<cmath>#include<algorithm>#include<vector>using namespace std;#define all(x) (x).begin(), (x).end()#define for0(a, n) for (int (a) = 0; (a) < (n); (a)++)#define for1(a, n) for (int (a) = 1; (a) <= (n); (a)++)#define sqr(x) ((x)*(x))#define eps (1e-7)typedef long long ll;typedef pair<int, int> pii;const int INF =0x3f3f3f3f;const int maxn= 1000 ;const double PI=4.0*atan(1.0);int n,N;struct Seg{ double le,ri; Seg(){} Seg(double le,double ri):le(le),ri(ri){} bool operator<(const Seg y)const { return ri<y.ri; }}a[2*maxn+10];void getSeg(int ind,double x,double y,double r){ double dis=sqrt( sqr(x)+sqr(y) ); double rad1= asin(r/dis); double Rad=atan2(y,x); double le=Rad-rad1; double ri=Rad+rad1; if(ri<=-PI) le+=2*PI,ri+=2*PI; else if(ri>PI) le-=2*PI,ri-=2*PI; a[ind]=Seg(le,ri); a[ind+n]=Seg(le+2*PI,ri+2*PI);}void work(){ sort(a+1,a+1+N); int ans=n; for(int i=1;i<=n;i++) { int tot=0; double now=-INF; for(int j=i;j<=i+n-1;j++) { double le=a[j].le; double ri=a[j].ri; if(le>=now) { now=ri; tot++; } } ans=min(ans,tot); } printf("%d\n",ans);}int main(){ int T;scanf("%d",&T); while(T--) { scanf("%d",&n); double x,y,r; for1(i,n) { scanf("%lf%lf%lf",&x,&y,&r); getSeg(i,x,y,r); } N=2*n; work(); } return 0;}
0 0
- hdu 4197 Popping Balloons 环状区间选点
- hdu 4197 Popping Balloons
- hdu 4197 Popping Balloons
- hdu 4883 区间选点
- HDU 4883 TIANKENG’s restaurant(区间选点)
- hdu 4883 TIANKENG’s restaurant(区间选点)
- HDU 4883(区间选点贡献经典问题)
- 区间选点
- 区间选点+区间覆盖
- 贪心算法-区间选点
- 贪心之区间选点
- 区间选点问题【贪心】
- uva10148Advertisement(区间选点)
- 区间覆盖,选点
- 区间选点问题
- uva10148 - Advertisement(区间选点)
- 贪心--区间选点问题
- 区间选点问题
- 反射获取class有几种方式,怎样得到对应的实例
- 多线程设计模式——Thread Confinement(串行线程封闭)模式
- output元素的追加和表单的验证
- Adobe Flash CC 2015常用快捷键——For程序员
- 巩固基础篇:经典二分查找模型及其应用
- hdu 4197 Popping Balloons 环状区间选点
- [学习笔记]C# Socket初试-客户端
- java动态代理实现
- Android应用程序(APK)的编译打包过程
- System.getProperty方法汇总
- android中需要牢记的单词(java篇)
- [转载]设置或更改服务器排序规则
- 代理(正反)
- 一台够靠谱的冰箱,让我的欧洲杯时光如此幸福