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;}
新聞熱點
疑難解答