nyoj 12 喷水装置(二)

题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=12

这道题自己没写网上找的代码,不过思路很清晰的主要思想就是先转化成直线上的线段覆盖问题,就是求用最少的线段数把整个区域都覆盖了,最终求的是所用的线段数,不能覆盖的输出0;

题目给出了点的坐标和半径,只用带入即可求出线段的左右边界,这题需要注意的一点就是利用贪心思想选取线段的时候,按左坐标由小到大排序,

对于下面几种情况的处理

View Code
 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<math.h>
 4 #include<algorithm>
 5 using namespace std;
 6 struct ps
 7 {
 8     double left;//**左交点**//
 9     double right;//**右交点**//
10 }w[10001];
11 bool comp(ps a,ps b)//**还是按照左交点的大小进行排序**//
12 {
13     if(a.left<b.left) return true;
14     return false;
15 }
16 int main()
17 {
18     int ncases,n,i,width,high,x,r,count,flag;
19     double len,sum,max;
20     scanf("%d",&ncases);
21     while(ncases--)
22     {
23         flag=1;sum=0;count=0;
24         scanf("%d %d %d",&n,&width,&high);
25         for(i=0;i<=n-1;i++)
26         {
27             scanf("%d %d",&x,&r);
28             len=(double)r*r-(double)high/2*high/2;
29             if(len>=0) {len=sqrt(len);}//**以前把这布直接并入到sqrt(len),结果忘了len可以小于0,一直WA**//
30             if(len<0) {len=0;}//**覆盖不到,这个长度就可以忽略掉**//
31             w[i].left=x-len;
32             w[i].right=x+len;
33         }
34         sort(w,w+n,comp);
35         while(sum<width)//**关键思想**//
36         {
37             max=0;//**代表比前一个装置能够辐射的范围往右延长的最大值**//
38             for(i=0;i<=n-1&&w[i].left<=sum;i++)//**w[i].left<=sum保证两个碰水装置可以相交,也就是说两点直接的能够完全覆盖**//
39             {
40                 if((w[i].right-sum)>max)//**找出既能保证完全覆盖又能保证这点能够达到的右交点最大,即需要的喷水装置最少**//
41                 {
42                     max=w[i].right-sum;//**找出最大值**//
43                 }
44             }
45             if(max==0)//**说明w[i].left>sum,表示其中一个点的右交点跟另外一个点的左交点没有连接上,即不能完全覆盖**//
46             {
47                 flag=0;
48                 break;
49             }
50             else
51             {
52                 sum=sum+max;//**更新能够覆盖的宽度**//
53                 count++;
54             }
55         }
56         if(flag==1)
57         {
58             printf("%d\n",count);
59         }
60         else
61         {
62             printf("0\n");
63         }
64     }
65     return 0;
66 }

 

posted @ 2012-05-03 21:49  我们一直在努力  阅读(330)  评论(0编辑  收藏  举报