NYOJ 12 喷水装置(二)

喷水装置(二)

时间限制: 3000 ms  |  内存限制: 65535 KB
难度: 4
描述
有一块草坪,横向长w,纵向长为h,在它的橫向中心线上不同位置处装有n(n<=10000)个点状的喷水装置,每个喷水装置i喷水的效果是让以它为中心半径为Ri的圆都被润湿。请在给出的喷水装置中选择尽量少的喷水装置,把整个草坪全部润湿。
输入
第一行输入一个正整数N表示共有n次测试数据。
每一组测试数据的第一行有三个整数n,w,h,n表示共有n个喷水装置,w表示草坪的横向长度,h表示草坪的纵向长度。
随后的n行,都有两个整数xi和ri,xi表示第i个喷水装置的的横坐标(最左边为0),ri表示该喷水装置能覆盖的圆的半径。
输出
每组测试数据输出一个正整数,表示共需要多少个喷水装置,每个输出单独占一行。
如果不存在一种能够把整个草坪湿润的方案,请输出0。
样例输入
2
2 8 6
1 1
4 5
2 10 6
4 5
6 5
样例输出
1
2

个人感受

这道题当时卡了我也是半天,非常无奈,主要思路就是贪心策略,把它的每一个的覆盖开始坐标和结束坐标都算一下,然后让能覆盖的长区间覆盖上去,如果中间有断档,则GG,上代码。

01. #include
02. #include
03. #include
04. #include
05. struct keer
06. {
07. int a,b;
08. double c,d;//c,d分别是1个喷水装置的开始和结束的坐标
09. } s[10005];
10. int f(keer x, keer y)//进行排序定义
11. {
12. if(x.c==y.c)
13. return x.d>y.d;
14. return x.c
15. }
16. using namespace std;
17. int main()
18. {
19. int t;
20. scanf("%d",&t);
21. while(t--)
22. {
23. int n;
24. double x,y;
25. scanf("%d%lf%lf",&n,&x,&y);
26. for(int i=0; i
27. {
28. scanf("%d%d",&s[i].a,&s[i].b);
29. s[i].c=s[i].a-sqrt(s[i].b*s[i].b-y*y/4.0);//计算开始的坐标
30. s[i].d=s[i].a+sqrt(s[i].b*s[i].b-y*y/4.0);//计算结束的坐标
31. }
32. sort(s,s+n,f);
33. int tt=0;
34. int o=0;
35. double endd=0;
36. while(endd
37. {
38. double opq=endd;
39. for(int i=0; i
40. {
41. if(opq>=s[i].c&&s[i].d>endd)//为使它能够完全覆盖,进行判断
42. {
43. endd=s[i].d;
44. }
45. }
46. if(opq==endd)//如果发现覆盖晚之后和上次的相同说明没有覆盖,输出0;
47. {
48. tt=1;
49. break;
50. }
51. else
52. {
53. o++;
54. }
55. }
56. if(tt)
57. printf("0\n");
58. else
59. printf("%d\n",o);
60. }
61. return 0;
62. }
//第一次写,别挑~!!!

你可能感兴趣的:(贪心算法)