• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
slon
nit-acm
博客园    首页    新随笔    联系   管理    订阅  订阅

hdu 4197 Popping Balloons

http://acm.hdu.edu.cn/showproblem.php?pid=4197

题目说要飞最少的飞镖把所有气球穿破。

对于任意一个气球,要把它打破,扔的飞镖必然是在它的两条切线的上下界内。

然后排序,枚举起点定义方向进行贪心。

View Code
 1 #include <iostream> 
 2 #include <stdio.h> 
 3 #include <string.h> 
 4 #include <math.h> 
 5 #include <algorithm> 
 6 #include <limits.h> 
 7 using namespace std;
 8 #define PI 3.14159265358979
 9 #define eps 1e-6
10 struct node{
11     double l,r;
12 }w[1010];
13 bool cmp(const node &a,const node &b){
14     return a.l<b.l;
15 }
16 int zero(double x){
17     return fabs(x)<eps;
18 }
19 int dd(double x,double y){
20     return fabs(x-y)<eps;
21 }
22 int dy(double x,double y){
23     return x>y+eps;
24 }
25 int xy(double x,double y){
26     return x+eps<y;
27 }
28 int dyd(double x,double y){
29     return x+eps>y;
30 }
31 int xyd(double x,double y){
32     return y+eps>x;
33 }
34 int live(double l,double r,double x){
35     if(xyd(l,r)&&xyd(l,x)&&xyd(x,r)) return 1;
36     if(dy(l,r)&&(xyd(l,x)||xyd(x,r))) return 1;
37     return 0;
38 }
39 int main(){
40     int T,n,a,b,c;
41     scanf("%d",&T);
42     while(T--){
43         scanf("%d",&n);
44         for(int i=0;i<n;++i){
45             scanf("%d%d%d",&a,&b,&c);
46             double dis=double(a*a+b*b);
47             double s;
48             double tr=asin(double(c)/sqrt(dis));
49             if(!a){
50                 if(b>=0) s=PI/2;
51                 else s=-PI/2;
52             }
53             else{
54                 s=atan(double(b)/a);
55                 if(a<0){
56                     if(b<0) s-=PI;
57                     else s+=PI;
58                 }
59             }
60             w[i].l=s-tr;
61             w[i].r=s+tr;
62             if(w[i].l<-PI) w[i].l+=2*PI;
63             if(w[i].r>PI) w[i].r-=2*PI;
64         }
65         sort(w,w+n,cmp);
66         int ans=n;
67         for(int i=0;i<n;++i){
68             double L,R;
69             int num=1;
70             L=w[i].l,R=w[i].r;
71             for(int j=1;j<n;++j){
72                 int v=(i+j)%n;
73                 if(!live(L,R,w[v].l)){
74                     L=w[v].l;
75                     R=w[v].r;
76                     num++;
77                 }
78                 else{
79                     L=w[v].l;
80                     if(live(L,R,w[v].r)) R=w[v].r;
81                 }
82             }
83             ans=min(ans,num);
84         }
85         printf("%d\n",ans);
86     }
87     return 0;
88 }

 





posted @ 2012-04-03 20:26  slon  阅读(348)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3