您的位置:首页 > 其它

uva_10382_Watering Grass( 貪心 )

2013-04-23 14:13 288 查看
題意:

噴水裝置能否覆蓋草坪,其實隻取決於圖中每個圓藍色部分能否將草坪覆蓋,這樣我們就將問題轉化成了有若幹線段,求覆蓋一個指定區間最少要多少條線段

分析:

題目可以作出如下轉化:



從最左開始使用貪心策略每次選擇一個包含當前最右的區間且擴張最遠的圓

Code:

#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;

#define MAXN    10000 + 10
#define REPI(i, s, e)   for(int i = (s); i <= (e); i ++)

typedef struct QNode_ {
double x, y;
}QNode;

QNode area[MAXN];
const double eps = 1e-9;

int cal(int n, double l)
{
int cnt = 0;
double start = 0.0;
REPI(i, 1, n) {
if( area[i].x-start <= eps ) {
int idx = i, tar;
double delta = 0.0;
while( idx <= n && area[idx].x-start <= eps ) {
if( delta < area[idx].y ) {
delta = area[idx].y, tar = idx;
}
idx += 1;
}
cnt += 1;
start = area[tar].y;
if( l-start <= eps ) {
return cnt;
}
}
}
if( l-start <= eps ) {
return cnt;
}
return -1;
}

inline int cmp(const QNode &a, const QNode &b)
{
if( a.x == b.x ) {
return a.y > b.y;
}
return a.x < b.x;
}

int main(int argc, char const *argv[])
{
#ifndef ONLINE_JUDGE
freopen("test.in", "r", stdin);
#endif
int n;
double l, w, p, r;
while( ~scanf("%d %lf %lf", &n, &l, &w) ) {
REPI(i, 1, n) {
scanf("%lf %lf", &p, &r);
double delta = sqrt(r*r-w*w/4.0);
area[i].x = p-delta, area[i].y = p+delta;
}
sort(area+1, area+1+n, cmp);
printf("%d\n", cal(n, l));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: