「One Book 1.1例2」植樹
【出典】
一般的な質問バンク
-1424 UVA-10382
LibreOJ-10002
Kattis-grass
vjudge
各質問バンクの質問は同じ意味ですが、入力形式とデータ範囲が少し異なります。
【タイトル説明】
長い
メートル、ワイド
メーターの芝生がいっぱい
灌漑スプリンクラー。各ノズルは芝生の中心線上に設置されています(両側から)
M)。各スプリンクラーの位置(芝生の中心線の左端からの距離)と、スプリンクラーがカバーできる散水範囲がわかっています。
質問:芝生全体を同時に灌漑する場合、少なくともいくつのスプリンクラーを開く必要がありますか?
【入力フォーマット】
入力には、テストデータのいくつかのセットが含まれています。
最初の行の整数 はデータグループの数を表します。
各データセットの最初の行は整数です および ;
次のn行では、各行に2つの整数が含まれ、スプリンクラーの位置と灌漑半径を示します(上の図は、最初のデータセットのサンプル入力で説明されているケースです)。
【出力フォーマット】
テストデータのセットごとに数値が出力され、芝生全体を灌漑するために必要なスプリンクラーの最小数が示されます。すべてのスプリンクラーがオンになっていて、芝生全体に水をやることができない場合、出力 。
【入力例】
3
8 20 2
5 3
4 1
1 2
7 2
10 2
13 3
16 2
19 4
3 10 1
3 5
9 3
6 1
3 10 1
5 3
1 1
9 1
【出力例】
6
2
-1
【データ範囲】
100%データの場合、n≤15000。
【分析】
貪欲。
スプレーヘッドによってスプレーされる水の有効範囲を見つけ、芝生の幅よりもスプレーの直径が小さいスプレーヘッドをフィルターで除去します。
次に、この問題は、間隔のフルカバレッジ問題に変換できます。 間隔、次に ラインセグメントの始点と終点(これは閉じた間隔であることに注意してください)間隔全体を完全にカバーするための最小数のラインセグメントを見つけます。
各セクションを左端のポイントの昇順で配置します。ここでの貪欲な戦略は、完全にカバーされるまで、選択可能な線分の最大の右端のポイントを毎回選択することです。
【コード】
Yitongtong / LibreOJ:
#pragma GCC optimize(3,"Ofast","inline")
#pragma G++ optimize(3,"Ofast","inline")
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#define RI register int
#define re(i,a,b) for(RI i=a; i<=b; i++)
#define ms(i,a) memset(a,i,sizeof(a))
#define MAX(a,b) (((a)>(b)) ? (a):(b))
#define MIN(a,b) (((a)<(b)) ? (a):(b))
using namespace std;
typedef long long LL;
const int N=15005;
struct Node {
double l,r;
bool operator < (const Node &rhs) const {
return l<rhs.l;
}
} a[N];
int main() {
int T;
scanf("%d",&T);
while(T--) {
int n,L,W;
scanf("%d%d%d",&n,&L,&W);
int cnt=0;
for(int i=1; i<=n; i++) {
int x,r;
scanf("%d%d",&x,&r);
if(r<W/2.0) continue;
double tmp=sqrt(r*r-W*W/4.0);
a[++cnt].l=1.0*x-tmp;
a[cnt].r=1.0*x+tmp;
}
sort(a+1,a+cnt+1);
double t=0;
int ans=0,i=1,flag=0;
while(t<L) {
ans++;
double s=t;
while(a[i].l<=s && i<=cnt) {
if(t<a[i].r) t=a[i].r;
i++;
}
if(t==s && s<L) {
printf("-1\n");
flag=1;
break;
}
}
if(!flag) printf("%d\n",ans);
}
return 0;
}
UVA / Kattis:
//注:UVAに入力する変数の型は浮動小数点を使用する必要があります
#pragma GCC optimize(3,"Ofast","inline")
#pragma G++ optimize(3,"Ofast","inline")
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#define RI register int
#define re(i,a,b) for(RI i=a; i<=b; i++)
#define ms(i,a) memset(a,i,sizeof(a))
#define MAX(a,b) (((a)>(b)) ? (a):(b))
#define MIN(a,b) (((a)<(b)) ? (a):(b))
using namespace std;
typedef long long LL;
const int N=1e4+5;
struct Node {
double l,r;
bool operator < (const Node &rhs) const {
return l<rhs.l;
}
} a[N];
int main() {
int n,L;
double W;
while(~scanf("%d%d%lf",&n,&L,&W)) {
int cnt=0;
for(int i=1; i<=n; i++) {
double x,r;
scanf("%lf%lf",&x,&r);
if(r<W/2) continue;
double tmp=sqrt(r*r-W*W/4);
a[++cnt].l=x-tmp;
a[cnt].r=x+tmp;
}
sort(a+1,a+cnt+1);
double t=0;
int ans=0,i=1,flag=0;
while(t<L) {
ans++;
double s=t;
while(a[i].l<=s && i<=cnt) {
if(t<a[i].r) t=a[i].r;
i++;
}
if(t==s && s<L) {
printf("-1\n");
flag=1;
break;
}
}
if(!flag) printf("%d\n",ans);
}
return 0;
}