TopCoder SRM 564 Div1 Easy KnightCircuit2
問題
w x hのチェス番がある。
好きなマスにナイトを置いて、自由に動かす。
同じマスを何回通ってもよい。
このとき、ナイトが一度以上行けたマスの数は最大でいくつになるか、求めよ。
制約条件
w, h≦45000
方針
サンプルより100 x 100のときはすべてのマスにいけることがわかる。
なので、w≧100かつh≧100のときは全部のマスに行ける。
w≦100またはh≦100のとき、
w * h≦4500000なので、全探索して間に合う。
ソースコード
const int dy[] = {-2, -2, -1, 1, 2, 2, 1, -1}, dx[] = {-1, 1, 2, 2, 1, -1, -2, -2}; int p[10000], sz[10000]; int root(int x){ if(x == p[x]) return x; return p[x] = root(p[x]); } class KnightCircuit2 { public: int maxSize(int w, int h) { if(w < h) swap(w, h); if(h == 1) return 1; if(h == 2){ return (w + 1) / 2; } if(w < 100 && h < 100) return calc(w, h); return w * h; } int calc(int w, int h){ rep(i, h * w) p[i] = i, sz[i] = 1; int ans = 0; rep(i, h) rep(j, w) rep(d, 8){ int ny = i + dy[d], nx = j + dx[d]; if(ny < 0 || ny >= h || nx < 0 || nx >= w) continue; int a = root(ny * w + nx), b = root(i * w + j); if(a != b){ p[b] = a; sz[a] += sz[b]; } } rep(i, h * w) ans = max(ans, sz[i]); return ans; } };