2008-12-30
SRM382 Div1 Easy: CollectingRiders
問題読み違えてた。これ本番に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;
}
};
コメント
トラックバック - https://topcoder-g-hatena-ne-jp.jag-icpc.org/n4_t/20081230