題目描述:點擊打開連接ios
題意是在某一時刻t會有一個隕石落下來,會落到座標爲x,y的地方,隕石落下來以後不但x,y會遭到破壞,和x,y四鄰接的點也會被破壞。如今Bessie的初始位置在原點,每個單位時間只能平行於座標軸,移動一個單位距離,題目要求須要幾個單位時間Bessie才能移動到安全的地方(只能運動在座標軸和第一象限)。因爲隕石落下來以前,某個點仍是能夠走的,直到t時刻隕石落下來破壞掉該點。數組
明確題意後首先想到的是BFS,預處理是這題的難點,因爲某個點遭到破壞後就不能走了,所以若是有屢次遭破壞只要記錄改點遭破壞的最先的時間就能夠了。bfs的時候若是移動步數大於等於該點被破壞的時間,那麼該節點就不能被擴展。直到走到不會被隕石破壞的點爲止。安全
代碼以下:spa
數組mp記錄了每一個點被隕石破壞的最先時間,若是不會被破壞則用-1表示(因爲題目中t能夠是0,所以不能用0表示不會被破壞,在這裏wa了一次)code
#include <iostream> #include <algorithm> #include <string> #include <queue> using namespace std; int mp[309][309]; int dir[4][2] = {{1,0}, {-1,0}, {0,-1}, {0,1}}; int visit[309][309]; struct State { int x, y, step; State(int x, int y, int step) : x(x), y(y), step(step) {} }; bool inFirstQuadrant( int x, int y ) { if ( x >= 0 && y >= 0 ) return true; return false; } void setPoint(int x, int y, int t) { if ( mp[x][y] == -1 ) mp[x][y] = t; else mp[x][y] = min(mp[x][y], t); } void destroyPoint( int x, int y, int t ) { setPoint(x, y, t); for ( int i=0; i<4; i++ ) { int tx = x + dir[i][0]; int ty = y + dir[i][1]; if ( inFirstQuadrant( tx, ty ) ) setPoint( tx, ty, t ); } } void BFS() { State origin( 0, 0, 0 ); queue<State> Q; Q.push( origin ); visit[0][0] = 1; while( ! Q.empty() ) { State cur = Q.front(); Q.pop(); if ( mp[cur.x][cur.y] == -1 ) { cout << cur.step << endl; return; } for ( int i=0; i<4; i++ ) { int x = cur.x + dir[i][0]; int y = cur.y + dir[i][1]; if ( inFirstQuadrant(x, y) && !visit[x][y]) { if ( cur.step + 1 < mp[x][y] || mp[x][y] == -1) { State p( x, y, cur.step + 1 ); Q.push( p ); visit[x][y] = 1; } } } } cout << -1 << endl; } int main() { int m; while ( cin >> m ) { memset( mp, -1, sizeof(mp) ); memset( visit, 0, sizeof(visit) ); int x, y, t; for ( int i=0; i<m; i++ ) { cin >> x >> y >> t; destroyPoint( x, y, t ); } BFS(); } return 0; }