Hatena::Grouptopcoder

naoya_t@topcoder RSSフィード

2008-12-30

SRM382 Div1 Easy: CollectingRiders

| 03:01 | SRM382 Div1 Easy: CollectingRiders - naoya_t@topcoder を含むブックマーク はてなブックマーク - SRM382 Div1 Easy: CollectingRiders - naoya_t@topcoder SRM382 Div1 Easy: CollectingRiders - naoya_t@topcoder のブックマークコメント

問題読み違えてた。これ本番に1時間15分で解けるだろうか。

  • ボード上のある位置について
    • 各駒がそこに辿り着くのに必要な手数を数える。不可能な場合もある。
    • 全駒がそこに(何手かで)辿り着ける場合、合計何手か
  • という風に全ての位置について計算し、合計の最も少ないのが答え

サンプルケースが全部通れば通る感じ。

#define sz(a)  int((a).size())
#define pb  push_back
#define all(c)  (c).begin(),(c).end()
#define tr(c,i)  for(typeof((c).begin()) i=(c).begin(); i!=(c).end(); i++)
#define rep(var,n)  for(int var=0;var<(n);var++)
#define found(s,e)  ((s).find(e)!=(s).end())
#define remove_(c,val) (c).erase(remove((c).begin(),(c).end(),(val)),(c).end())

vector<set<pair<int,int> > > moves(10);
vector<pair<int,int> > d(8);

class Piece{
 public:
  int x, y, k;
  Piece(int x_, int y_, int k_){x=x_;y=y_;k=k_;}
};

class CollectingRiders {
  int w,h;
  int gx,gy;
  bool bd[10][10], bdt[10][10], bdv[10][10];
  
  int moves_needed(int xp,int yp){
    rep(x,w) rep(y,h) bd[x][y]=bdv[x][y]=false;
    int time=0;
    if(xp==gx && yp==gy) return 0;
    bd[xp][yp]=bdv[xp][yp]=true;
    while (true) {
      int cnt=0;
      rep(x,w) rep(y,h) bdt[x][y]=false;
      rep(x,w) rep(y,h) {
        if (!bd[x][y]) continue;
        rep(i,8){
          int x_=x+d[i].first, y_=y+d[i].second;
          if ((0<=x_ && x_<w) && (0<=y_ && y_<h)) {
            bdt[x_][y_]=true;
            if(!bdv[x_][y_]){ bdv[x_][y_]=true; cnt++; }
          }
        }
      }
      time++;
      if (bdt[gx][gy]) return time;

      rep(x,w) rep(y,h) bd[x][y]=bdt[x][y];
      if (cnt==0) return -1;
    }
  }
    
 public:
  int minimalMoves(vector<string> board) {
    h=sz(board), w=board[0].length();

    d[0].first = 2; d[0].second = 1;
    d[1].first = 1; d[1].second = 2;
    d[2].first = -1; d[2].second = 2;
    d[3].first = -2; d[3].second = 1;
    d[4].first = -2; d[4].second = -1;
    d[5].first = -1; d[5].second = -2;
    d[6].first = 1; d[6].second = -2;
    d[7].first = 2; d[7].second = -1;

    moves[0].insert(make_pair(0,0));
    for (int i=1;i<=9;i++){
      tr(moves[i-1],it){
        int x=it->first,y=it->second;
        rep(j,8){
          int dx=d[j].first, dy=d[j].second;
          moves[i].insert(make_pair(x+dx,y+dy));
        }
      }
    }

    vector<Piece*> pieces;
    rep(y,h) rep(x,w){
      int c = board[y][x]; if (c!='.') pieces.pb(new Piece(x,y,c-'0'));
    }
    int np=sz(pieces);
    if (np==1) return 0;

    int total_min=INT_MAX;
    for(gx=0;gx<w;gx++) {
      for(gy=0;gy<h;gy++) {
        int total=0;
        rep(i,np){
          Piece* p = pieces[i];
          int mn = moves_needed(p->x,p->y), mn_min;
          if (mn < 0) goto next_xy;
          mn_min = mn/p->k;
          if (mn%p->k > 0) mn_min++;
          total += mn_min;
        }
        if(total<total_min) total_min=total;
     next_xy:
        ;
      }
    }

    tr(pieces,p) delete *p;

    return (total_min==INT_MAX) ? -1 : total_min;
  }
};
トラックバック - http://topcoder.g.hatena.ne.jp/n4_t/20081230