Codeforces #156 Div1 B (256 B) Mr. Bender and Square
問題
n x nの行列がある。
それぞれの成分はスイッチで、ONかOFFの状態をとる。
1秒ごとに、ONに隣接するOFFのスイッチはONになる。
最初、(x, y)のスイッチだけがONのとき、オンになっているスイッチがc個以上になるには何秒かかるか、求めよ。
制約条件
n≦10^9
1≦x, y≦n
c≦min(n^2, 10^9)
方針
t秒後にONになっているスイッチの数は比較的簡単に求められる。
これは、単調増加するため、二分探索で答えを見つければよい。
t秒後にONになっているスイッチは、頑張って数えるのだが、
(x, y)の(0,0)側の1/4だけを数え、あとの部分は対称性を利用して、同じ関数で求めればよい。
ソースコード
ll n, x, y, c; ll calc2(ll t, ll x, ll y){ if(x + y <= t) return (x + 1) * (y + 1); ll res = (t + 1) * (t + 2) / 2; ll a = -(x - t), b = -(y - t); if(a > 0) res -= a * (a + 1) / 2; if(b > 0) res -= b * (b + 1) / 2; return res; } ll calc(ll t, ll x, ll y){ ll res = -3; res -= min(t, x); res -= min(t, y); res -= min(t, max(0ll, n - 1 - y)); res -= min(t, max(0ll, n - 1 - x)); rep(i, 2) rep(j, 2){ res += calc2(t, i ? x : n - 1 - x, j ? y : n - 1 - y); } return res; } int main(){ cin >> n >> x >> y >> c; x--; y--; int lo = -1, hi = 2 * n, mid; while(lo + 1 < hi){ mid = ll(lo + hi) / 2; if(calc(mid, x, y) >= c) hi = mid; else lo = mid; } cout << hi << endl; return 0; }