POJ 3258 : River Hopscotch
概要
スタートの石とゴールの石が川の中にあって,その間の距離がLだけ離れている.スタートとゴールの間には,N個の石が一列に並んでいて,i番目の石はスタートからd_iだけ離れた位置にある.
スタートとゴールの石をM個以下だけ取り除いて,石(スタートとゴールも含む)の間の距離の最小値を最大化したい.
解法
許容する距離Dを仮定して二分探索.
距離Dだけ離せるかの判定は,スタートからDより小さい距離にある石を削除.その結果,残る石の中でスタートからの距離が最小のものを選び,それについて同様の処理を施す.これを続けていって最終的に削除した石の個数がM以下か確認すればいい.
int L, N, M; int d[50010]; bool C(int a){ int s = 0, cnt = 0; for(int i = 0; i < N; ++i){ if(d[i] - s < a) ++cnt; else s = d[i]; } if(L - s < a) ++cnt; return cnt <= M; } int main(){ scanf("%d%d%d", &L, &N, &M); for(int i = 0; i < N; ++i){ scanf("%d", &d[i]); } sort(d, d + N); int b = min(L - d[N-1], d[0]); for(int i = 1; i < N; ++i){ b = min(b, d[i] - d[i-1]); } int res = -1; int lb = 1, ub = L; while(lb <= ub){ int mid = (lb + ub) / 2; if(C(mid)){ res = mid; lb = mid + 1; } else{ ub = mid - 1; } } printf("%d\n", res); return 0; }