Div1 Hardはまさかの1100ptで驚愕したけど、Div2はそこまで難しくない。
http://community.topcoder.com/stat?c=problem_statement&pm=12710
問題
2次元フィールド上でAliceとBobの初期位置および地形が与えられる。
AliceとBobは交互に隣接マスに移動する。
Aliceの移動経路が与えられるとき、BobがAliceから逃げ切れる(同一マスに止まらずに済む)かどうかを答えよ。
解法
Bの移動可能マスを毎ターン全列挙し、Aliceの移動が完了するまでに移動可能マスが0個になるかどうかを判定すればよい。
フィールドサイズH*W、移動ターンMに対し、計算量はO(HWM)なのでさほど問題ない。
string check (vector <string> field, vector <string> moves) { bool okok[2][51][51]; int ax,ay; int H=field.size(); int W=field[0].size(); ZERO(okok); int y,x,i,d; FOR(y,H) FOR(x,W) { if(field[y][x]=='A') ay=y,ax=x,field[y][x]='.'; if(field[y][x]=='B') okok[0][y][x]=true,field[y][x]='.'; } string M; FOR(x,moves.size()) M+=moves[x]; FOR(i,M.size()) { int cur=i%2,tar=(i%2)^1; ZERO(okok[tar]); if(M[i]=='U') ay--; if(M[i]=='D') ay++; if(M[i]=='L') ax--; if(M[i]=='R') ax++; okok[cur][ay][ax]=false; FOR(y,H) FOR(x,W) { if(okok[cur][y][x]==false) continue; FOR(d,4) { int dx[4]={1,-1,0,0}, dy[4]={0,0,1,-1}; int cx=x+dx[d],cy=y+dy[d]; if(cx<0 || cy<0 || cx>=W || cy>=H) continue; if((cx!=ax || cy!=ay)&&field[cy][cx]=='.') okok[tar][cy][cx]=true; } } } FOR(y,H) FOR(x,W) if(okok[M.size()%2][y][x]) return "Bob wins"; return "Alice wins"; }
まとめ
Div2は意外とシンプルな問題。
普通だと計算量が心配だけど、H,W<=50、M<=2500と数値も小さいので大丈夫。