3 21 2-3 12 11 20 20 0Sample OutputCase 1: 2Case 2: 1给定海岛个数、雷达半径以及各海岛坐标,求能覆盖所有海岛的最小雷达数。
贪心策略依然是从左往右,尽量让每颗雷达覆盖最大岛屿数。
对于每个点先求出以该点为圆心,d为半径的圆在x轴上的交点,左右交点就是覆盖此海岛的雷达所在的区间。对于每个区间,按照区间的右端点排序。
从最左边开始贪心,对于第一个右端点x0,所有左端点<x0的海岛都会与x0共用一个雷达
#include<iostream>#include<cmath>#include<cstring>#include<cstdio>#include<algorithm>#define inf 0x3f3f3f3f#define ll long longusing namespace std;struct node{ int x,y;}q[1010];struct xnode{ double l,r;}xn[1010];bool cmp(xnode a,xnode b){ if(a.r==b.r) return a.l<b.l; return a.r<b.r;}bool visited[1010];int main(){ int n,d; int kcase=1; while(cin>>n>>d) { if(n==0) return 0; bool flag=0; for(int i=1;i<=n;i++) { cin>>q[i].x>>q[i].y; if(q[i].y>d) flag=1; } if(flag==1||d==0) { cout<<"Case "<<kcase++<<": "<<-1<<endl; continue; } for(int i=1;i<=n;i++) { double len=sqrt(1.0*d*d-q[i].y*q[i].y); xn[i].l=q[i].x-len; xn[i].r=q[i].x+len; } sort(xn+1,xn+n+1,cmp); int ans=0; memset(visited,0,sizeof(visited)); for(int i=1;i<=n;i++) if(!visited[i]) { visited[i]=1; ans++; for(int j=i+1;j<=n;j++) if(!visited[j]&&xn[j].l<=xn[i].r) visited[j]=1; } cout<<"Case "<<kcase++<<": "<<ans<<endl; } return 0;}
新闻热点
疑难解答