标签:
在x轴上方分布着一些岛(坐标表示),x轴上有覆盖半径为r的雷达,求覆盖所有小岛最少需要多少个雷达。
刚开始我天真地想求出每个点作圆与x轴的右焦点,后来发现y又不一样,就这样傻傻地写了一个自以为正确的(完全错误)程序。后来仔细想了想应该这样做:
求出每个点在坐标上的区间,按坐标的右边的点排序。若区间的右边的点end,在下一个区间的范围内,继续判断。直到
1 #include<iostream> 2 #include<algorithm> 3 #include<cmath> 4 using namespace std; 5 struct Location 6 { 7 double x;double y; 8 }; 9 struct Section 10 { 11 double x1;double x2; 12 }; 13 const int MAX_N=1000; 14 Location Loc[MAX_N]; 15 Section Sec[MAX_N]; 16 int results[MAX_N]; 17 int N,D; 18 //计算每个点所对应的区间 ,注意section b需要计算,函数参数前不能加const 19 void calculate(const Location& a, Section& b) 20 { 21 double temp = sqrt(D*D-a.y*a.y); 22 b.x1 = temp+a.x; 23 b.x2 = a.x-temp; 24 return ; 25 } 26 //用end排序 27 bool is_greater(const Section& a,const Section& b) 28 { 29 return (a.x1<b.x1)||(a.x1==b.x1 && a.x2<=b.x2); 30 } 31 int solve() 32 { 33 //检查是否有解 34 bool found=false; 35 int i; 36 for(i=0;i<N;i++) 37 { 38 if(Loc[i].y>D) 39 { 40 found=true; 41 break; 42 } 43 } 44 if(found) 45 { 46 return -1; 47 } 48 for(i=0;i<N;i++) 49 { 50 calculate(Loc[i],Sec[i]); 51 } 52 sort(Sec,Sec+N,is_greater); 53 int k=0; 54 int q=0; 55 int num=0; 56 while(k<N) 57 { 58 k=q+1; 59 //判断end是否在下个区间里 60 while(Sec[q].x1>=Sec[k].x2 && Sec[q].x1<=Sec[k].x1 && k<N) 61 { 62 k++; 63 } 64 q=k; 65 num++; 66 } 67 return num; 68 } 69 int main() 70 { 71 int times=0; 72 while(cin>>N>>D,N||D) 73 { 74 int i=0; 75 for(;i<N;i++) 76 { 77 cin>>Loc[i].x>>Loc[i].y; 78 } 79 results[times]=solve(); 80 times++; 81 } 82 for(int l=0;l<times;l++) 83 { 84 cout<<"Case "<<l+1<<": "<<results[l]<<endl; 85 } 86 return 0; 87 }
end不在某个范围时,消耗一个雷达;将end更新为上次不在范围内的end,循环进行,知道覆盖所有点。
标签:
原文地址:http://www.cnblogs.com/xlsryj/p/4740067.html