こちらも割とすんなり。
https://yukicoder.me/problems/no/2412
問題
2次元グリッドが与えられる。
一部マスは通過不可である。
ここで、3*3マスのサイズの駒を、左上から右下マスに移動したい。
駒は8近傍に1マス分移動できる。ただし移動先に通過不可マスがあってはならない。
通過不可マスを増やし、駒を左上から右下に移動不可にしたい。
最小何マス追加すればよいか。
解法
2マス移動不可マスを追加すれば、駒は左上マスから移動できなくなる。
そこで、解を判定するには
- 1マスも通過不可マスを追加しないケース
- 1マスだけ通過不可マスを追加するケース
を考えればよい、後者は全マス総当たりしても間に合う。
int H,W; string S[2424]; int ok[2424][2424]; int D[2424][2424]; int hoge() { int y,x,dy,dx; FOR(y,H-2) FOR(x,W-2) { D[y][x]=0; ok[y][x]=1; for(dy=y;dy<=y+2;dy++) for(dx=x;dx<=x+2;dx++) if(S[dy][dx]=='#') ok[y][x]=0; } D[0][0]=1; queue<int> Q; Q.push(0); while(Q.size()) { int cy=Q.front()/10000; int cx=Q.front()%10000; Q.pop(); if(cy==H-3&&cx==W-3) return 0; for(y=cy-1;y<=cy+1;y++) for(x=cx-1;x<=cx+1;x++) { if(x<0||x>W-3||y<0||y>H-3) continue; if(ok[y][x]==0) continue; if(D[y][x]==1) continue; D[y][x]=1; Q.push(y*10000+x); } } return 1; } void solve() { int i,j,k,l,r,x,y; string s; cin>>H>>W; FOR(y,H) cin>>S[y]; if(hoge()) { cout<<0<<endl; return; } FOR(y,H) FOR(x,W) if(S[y][x]=='.') { if(y<=2&&x<=2) continue; if(y>=H-3&&x>=W-3) continue; S[y][x]='#'; if(hoge()) { cout<<1<<endl; return; } S[y][x]='.'; } cout<<2<<endl; }
まとめ
考察すると最大値が小さくなるの、Codeforcesでしばしば現れるイメージ。