CODE FESTIVAL QUAL A - D 壊れた電車
問題
方針
答えの時間 T
を決めて,それが可能か判定する関数を作り,二分探索.
現時点で修理が完了した最も右の車両を変数 done
で持ち,
そこより右のどこまで終わらせられるかを求める.
二分探索は第一感でわかったけど判定部分が書けなかった…
実装
ll n;
ll m;
ll x[100010];
bool check(ll T){
if(T == -1) return false;
ll done = 0;
rep(i,m){
ll nx = done;
{
ll rem = T;
rem -= x[i] - (done + 1);
if(rem >= 0){
ll can = (done + 1) + rem;
nx = max(nx, can);
}
}
{
ll rem = T;
rem -= x[i] - (done + 1);
if(rem >= 0){
ll can = x[i] + rem/2;
nx = max(nx, can);
}
}
done = min(i != m-1 ? x[i+1]-1 : n, nx);
}
return done == n;
}
ll solve(){
if(m == 1) return n-1 + min(x[0]-1, n-x[0]);
ll l = -1, r = n*2;
// xxxxoooo
// lr
while(l+1 < r){
ll m = (l+r)/2;
if(check(m)) r = m;
else l = m;
}
return r;
}
signed main(){
while(cin >> n){
cin >> m;
rep(i,m) cin >> x[i];
cout << solve() << endl;
}
}