题目:x轴上方有n个目标点,坐标全为整数,为了扫描到他们,在x轴上安放雷达,每一个雷达扫描半径为d,问至少安放多少雷达。
思路:首先,以每个岛为圆心,画出一个圆,应该与x轴有1或2个交点(否则直接输出不可能了)。
这样,n个点就有n个区间,我们以右端点作为排序键,进行排序。维护一个当前区间最小的右端点,当一个新的区间拿来比较的时候 ,若新区间的左端点小于维护的最小右端点,这说明这个新区间所代表的岛可以被旧雷达所扫到,不做动作,而假如新区间的左端点大于当前区间的右端点,说明要新雷达了,雷达数+1,并且新区间变为当前区间,其右端点为当前区间最小右端点。
- #include<iostream>
- #include<cmath>
- #include<algorithm>
- using namespace std;
- const int island_max=1000;
- class Node
- {
- public:
- float x;
- float y;
- };
- class Region
- {
- public:
- float left;
- float right;
- };
- Node island[island_max];
- Region island_re[island_max];
- bool cmp(Region a,Region b)
- {
- return a.right<b.right;
- }
- int main()
- {
- int num;
- float rad;
- for(;;)
- {
- //**********输入每个点的坐标,并判断是否有解*****
- cin>>num>>rad;
- if(!(num&&rad))
- break;
- bool flag = false;
- static int count = 1;
- for(int i=0;i<num;i++)
- {
- Node temp;
- cin>>temp.x>>temp.y;
- island[i]=temp;
- if(island[i].y>rad)
- flag = true;
- }
- if(flag)
- {
- cout<<"Case "<<count++<<": -1"<<endl;
- continue;
- }
- /*************算出每个点的区间 ******/
- for(int i=0;i<num;i++)
- {
- island_re[i].left = island[i].x-sqrt(rad*rad-island[i].y*island[i].y);
- island_re[i].right = island[i].x+sqrt(rad*rad-island[i].y*island[i].y);
- }
- sort(island_re,island_re+num,cmp); //根据交点的右坐标进行排序
- /***********根据每个区间算情况********/
- int radar = 1;
- float tmp;
- int i;
- for(i = 0,tmp = island_re[0].right;i<num-1;i++)
- {
- if(island_re[i+1].left>tmp)
- {
- radar++;
- tmp = island_re[i+1].right;
- }
- }
- cout<<"Case "<<count++<<": "<<radar<<endl;
- }
- system("pause");
- return 0;
- }