TopCoder SRM 382 Div1 Easy CollectingRiders

問題

チェスの駒でriderというものを考える。
一回の移動で、k-riderはk回以下のナイトの移動がまとめてできる。


チェス盤のboard[i][j]が数字kのとき、
(i,j)のマスにはk-riderがいる。'.'のときは何もない。


全てのriderを一つのマスに集めるために必要な手数の最小値を求めよ。
同じマスに複数の駒があってもよいものとする。

制約条件

boardの行≦10
boardの列≦10
board[i][j]は'0'-'9'または'.'

方針

集めるマスを全通り試して、全部集める。
あらかじめ全マス間のナイトでの移動回数をワーシャルフロイドで求めておくと書きやすい。

ソースコード

const int dy[]={-1,-2,-2,-1,1,2,2,1},dx[]={-2,-1,1,2,2,1,-1,-2};
int d[100][100];

class CollectingRiders {
  public:
  int minimalMoves(vector <string> board) {
    int h=board.size(),w=board[0].size();
    rep(i,h*w)rep(j,h*w)d[i][j]=i==j?0:inf;
    rep(i,h)rep(j,w)rep(k,8){
      int y=i+dy[k],x=j+dx[k];
      if(y<0||x<0||y>=h||x>=w)continue;
      d[i*w+j][y*w+x]=1;
    }
    rep(k,h*w)rep(i,h*w)rep(j,h*w)d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
      
    int ans=inf;
    rep(g,h*w){
      int tmp=0;
      rep(i,h*w)if(isdigit(board[i/w][i%w])){
        int k=board[i/w][i%w]-'0';
        if(d[g][i]==inf)tmp=inf;
        else tmp+=(d[g][i]+k-1)/k;
      }
      ans=min(ans,tmp);
    }
    return ans>=inf?-1:ans;
  }
};