給定一個 n 行 m 列的地牢,其中 ‘.’ 表示可以通行的位置,’X’ 表示不可通行的障礙,牛牛從 (x0 , y0 ) 位置出發(fā),遍歷這個地牢,和一般的游戲所不同的是,他每一步只能按照一些指定的步長遍歷地牢,要求每一步都不可以超過地牢的邊界,也不能到達障礙上。地牢的出口可能在任意某個可以通行的位置上。牛牛想知道最壞情況下,他需要多少步才可以離開這個地牢。 輸入描述:
每個輸入包含 1 個測試用例。每個測試用例的第一行包含兩個整數(shù) n 和 m(1 <= n, m <= 50),表示地牢的長和寬。接下來的 n 行,每行 m 個字符,描述地牢,地牢將至少包含兩個 ‘.’。接下來的一行,包含兩個整數(shù) x0, y0,表示牛牛的出發(fā)位置(0 <= x0 < n, 0 <= y0 < m,左上角的坐標為 (0, 0),出發(fā)位置一定是 ‘.’)。之后的一行包含一個整數(shù) k(0 < k <= 50)表示牛牛合法的步長數(shù),接下來的 k 行,每行兩個整數(shù) dx, dy 表示每次可選擇移動的行和列步長(-50 <= dx, dy <= 50)
輸出描述:
輸出一行一個數(shù)字表示最壞情況下需要多少次移動可以離開地牢,如果永遠無法離開,輸出 -1。以下測試用例中,牛牛可以上下左右移動,在所有可通行的位置.上,地牢出口如果被設(shè)置在右下角,牛牛想離開需要移動的次數(shù)最多,為3次。
輸入例子:
3 3 … … … 0 1 4 1 0 0 1 -1 0 0 -1
輸出例子:
3
錯誤做法如下,利用動態(tài)規(guī)劃,每個位置存儲到達此位置的最短步數(shù),這個思路的問題是,由于二維移動所以在第一遍遍歷所有點的時候會跳過一些點,這些點之后還有可能到達。這樣就會漏掉一些點。
#include <iostream>#include <vector>#include <string>#include <algorithm>using namespace std;int main(){ int dungeon_rows, dungeon_cols; cin >> dungeon_rows >> dungeon_cols; //vector<vector<char>> *dung_vec=new vector<vector<char>>(dungeon_rows,vector<char>(dungeon_cols,0)); vector<vector<int>> dung_vec(dungeon_rows, vector<int>(dungeon_cols, 0)); for (int i = 0; i != dungeon_rows; ++i){ string in_put; cin >> in_put; for (int j = 0; j != dungeon_cols; ++j) { dung_vec[i][j] = in_put[j]; } } int start_cols, start_rows; cin >> start_rows >> start_cols; int step_num; cin >> step_num; vector<vector<int>> step_vec(step_num, vector<int>(2, 0)); for (int i = 0; i != step_num; ++i) { cin >> step_vec[i][0] >> step_vec[i][1]; } vector<vector<int>> dung_max_step(dungeon_rows, vector<int>(dungeon_cols, -1)); dung_max_step[start_rows][start_cols] = 0; for (int i = start_rows; i != dungeon_rows; ++i){ for (int j = start_cols; j != dungeon_cols; ++j) { if (dung_max_step[i][j] != -1) { for (int m = 0; m < step_num; ++m) { if ((0 <= (step_vec[m][0] + i) && (step_vec[m][0] + i)< dungeon_rows) && 0 <= (step_vec[m][1] + j)&&(step_vec[m][1] + j)< dungeon_cols) { if (dung_vec[i + step_vec[m][0]][j + step_vec[m][1]] == '.'&&dung_max_step[i][j] != -1) { if (dung_max_step[i + step_vec[m][0]][j + step_vec[m][1]] == -1) dung_max_step[i + step_vec[m][0]][j + step_vec[m][1]] = dung_max_step[i][j] + 1; else dung_max_step[i + step_vec[m][0]][j + step_vec[m][1]] = min(dung_max_step[i][j] + 1, dung_max_step[i + step_vec[m][0]][j + step_vec[m][1]]); } } } } } } for (int i = 0; i != start_rows; ++i){ for (int j = 0; j != start_cols; ++j) { if (dung_max_step[i][j] != -1) { for (int m = 0; m < step_num; ++m) { if ((0 <= (step_vec[m][0] + i) && (step_vec[m][0] + i)< dungeon_rows) && 0 <= (step_vec[m][1] + j) && (step_vec[m][1] + j)< dungeon_cols) { if (dung_vec[i + step_vec[m][0]][j + step_vec[m][1]] == '.'&&dung_max_step[i][j] != -1) { if (dung_max_step[i + step_vec[m][0]][j + step_vec[m][1]] == -1) dung_max_step[i + step_vec[m][0]][j + step_vec[m][1]] = dung_max_step[i][j] + 1; else dung_max_step[i + step_vec[m][0]][j + step_vec[m][1]] = min(dung_max_step[i][j] + 1, dung_max_step[i + step_vec[m][0]][j + step_vec[m][1]]); } } } } } } int max_step = -1; for (int i = 0; i != dungeon_rows; ++i){ for (int j = 0; j != dungeon_cols; ++j) { if(dung_max_step[i][j]==-1&&dung_vec[i][j]=='.') { cout<<-1<<endl; return 0; } if (max_step<dung_max_step[i][j]) max_step = dung_max_step[i][j]; } } cout << max_step << endl; return 0;}可以利用廣度優(yōu)先搜素的方法進行計算
#include <iostream>#include <vector>#include <string>#include <algorithm>#include <queue>#include <climits>using namespace std;struct Point{ int x,y; Point(int _x,int _y):x(_x),y(_y){}; Point go(int m,int n) {return Point(x+m,y+n);}};int main(){ int dungeon_rows, dungeon_cols; cin >> dungeon_rows >> dungeon_cols; //vector<vector<char>> *dung_vec=new vector<vector<char>>(dungeon_rows,vector<char>(dungeon_cols,0)); vector<vector<int>> dung_vec(dungeon_rows, vector<int>(dungeon_cols, 0)); for (int i = 0; i != dungeon_rows; ++i){ string in_put; cin >> in_put; for (int j = 0; j != dungeon_cols; ++j) { dung_vec[i][j] = in_put[j]; } } int start_cols, start_rows; cin >> start_rows >> start_cols; int step_num; cin >> step_num; vector<vector<int>> step_vec(step_num, vector<int>(2, 0)); for (int i = 0; i != step_num; ++i) { cin >> step_vec[i][0] >> step_vec[i][1]; } vector<vector<int>> dung_max_step(dungeon_rows, vector<int>(dungeon_cols, INT_MAX)); dung_max_step[start_rows][start_cols] = 0; queue<Point> que; que.push(Point(start_rows,start_cols)); while(!que.empty()) { Point temp=que.front(); que.pop(); for(int i=0;i!=step_num;++i) { if(temp.x+step_vec[i][0]>=0&&temp.x+step_vec[i][0]<dungeon_rows&&temp.y+step_vec[i][1]>=0&&temp.y+step_vec[i][1]<dungeon_cols&& dung_vec[temp.x+step_vec[i][0]][temp.y+step_vec[i][1]]=='.') { if(dung_max_step[temp.x+step_vec[i][0]][temp.y+step_vec[i][1]]>dung_max_step[temp.x][temp.y]+1) { dung_max_step[temp.x+step_vec[i][0]][temp.y+step_vec[i][1]]=dung_max_step[temp.x][temp.y]+1; que.push(Point(temp.x+step_vec[i][0],temp.y+step_vec[i][1])); } } } } int max_step=-1; for (int i = 0; i != dungeon_rows; ++i){ for (int j = 0; j != dungeon_cols; ++j) { if(dung_max_step[i][j]==INT_MAX&&dung_vec[i][j]=='.') { cout<<-1<<endl; return 0; } if (dung_vec[i][j]=='.'&&max_step<dung_max_step[i][j]) max_step = dung_max_step[i][j]; } } cout << max_step << endl; return 0;}新聞熱點
疑難解答