1. 程式人生 > >POJ 1328(模擬&貪心_A題)解題報告

POJ 1328(模擬&貪心_A題)解題報告

不能 pen sca 出現 情況下 stream 產生 code 減少

題目鏈接:http://poj.org/problem?id=1328

--------------------------------------------------------

題意:在平面直角坐標系上,給出多個點。尋找能覆蓋的圓的最小個數。

思路:乍一看容易陷入尋找圓的圓心的思路中,然而確定圓心不是一個很容易的事情,其確定方法與其他各點都有一定關系。所以這種思路不可取。然後先從最簡單的情況下考慮,如果縱坐標大於圓的半徑,那麽無論何種方式都不能滿足題意,所以輸出"-1"。由此獲得啟發,計算出每個點在y軸上的可行區間,然後判斷區間是否有重合的地方。如果重合,圓心可以放置再重合區間內,更新區間,直至每個區間都進行了判斷。

註意:1.提交時候出現了CE,註重代碼習慣,減少C、C++混合coding方式

2.本題的輸入數據註意邊界點(半徑為0,圓心位於y軸下方),雖然本題測評時沒有出現相關數據。

3.本題輸入數據類型有可能為double型,樣例都為int型,容易產生慣性思維,認為都為int型,要開double。

代碼:

技術分享圖片
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<map>
using namespace std;
int N =0;
int
d =0; const int n=1010; double A[n+5];double B[n+5]; double L[n+5];double H[n+5]; int main(void){ int c1 =0; while(scanf("%d%d",&N,&d)){ int flag = 1; if(N==0&&d==0) break; for(int i=0;i<N;i++){ scanf("%lf %lf",&A[i],&B[i]);
if(B[i]>d||B[i]<0||d<=0) flag = 0; } for(int j=0;j<N;j++){ L[j]=A[j]-sqrt(double(d*d-B[j]*B[j])); H[j]=A[j]+sqrt(double(d*d-B[j]*B[j])); } int num =1; for(int i=0;i<N;i++){ for(int j=i+1;j<N;j++){ if(L[i]>L[j]){ double tmp =L[i]; L[i]=L[j]; L[j]=tmp; tmp=H[i]; H[i]=H[j]; H[j]=tmp; } } } double ss=L[0]; double st=H[0]; for(int i=1;i<N;i++){ if(L[i]<=st){ if(H[i]<st) st=H[i]; }else{ st=H[i]; num++; } } c1++; if(flag) printf("Case %d: %d\n",c1,num); else printf("Case %d: %d\n",c1,-1); } return 0; }
View Code

POJ 1328(模擬&貪心_A題)解題報告