题目链接:http://poj.org/problem?id=1328
思路:贪心
一开始的思路:
1. 以第一个岛屿为圆心,d为半径画圆,记与x轴的焦点中较大的那个为第一个雷达的位置;
2. 以这个雷达位置为圆心,d为半径画圆,记下之后的岛屿中第一个不能被覆盖的;
3. 依次这样下去,直到不能找到这样的雷达;
但是题目中没有说坐标一定是整数所以不能以 坐标+=1 来遍历,在遍历的过程中也是有问题的debug了好久干脆放弃;
所以应该是记录以每个岛屿坐标为圆心,d为半径的圆与X交点的左右坐标,再除去包含重复的
ac代码:
#include <iostream> #include <algorithm> #include <cmath> using namespace std; #define MAX_N 1000000 int N; double D; struct island{ // 题目中没有说坐标一定是整数 double left; double right; }nisl[1005],llimit; bool Cmp(const island& a,const island& b){ return (a.left<b.left); } int main(void){ int cases=1; while(cin>>N>>D&&(N||D)){ double x,y; int flage=0; for(int i=0;i<N;i++){ cin>>x>>y; if(y>D) flage=1; else{ nisl[i].left=x-sqrt(D*D-y*y); nisl[i].right=x+sqrt(D*D-y*y); } } cout<<"Case "<<cases++<<": "; if(flage) cout<<"-1"<<endl; else{ int num=1; sort(nisl,nisl+N,Cmp); // for(int i=0;i<N;i++) // cout<<nisl[i].left<<endl; llimit=nisl[0]; //左端点 for(int i=1;i<N;i++){ if(nisl[i].left>llimit.right){ llimit=nisl[i]; num++; }else if(nisl[i].right<llimit.right){ // 画图不难看出需要在这种情况换左端点; llimit=nisl[i]; } } cout<<num<<endl; } } return 0; }