DFS和BFS 解棋盤遊戲(九度OJ 1091)
阿新 • • 發佈:2019-02-03
DFS利用遞迴,不必使用多餘的資料結構,實現簡單。但要注意剪枝。
BFS藉助佇列,往往在求最優解時使用。總是能找到最優解,某些情況下也要剪枝。
這兩種方法根據具體問題來使用。
以此題為例,DFS和BFS都可求解。
由於是求最優解,用BFS更為直接。
由於此題的不確定性,必須要考慮所有可能情況,結合剪枝。
題目1091:棋盤遊戲時間限制:1 秒
記憶體限制:32 兆
特殊判題:否
提交:616
解決:151
- 題目描述:
-
有一個6*6的棋盤,每個棋盤上都有一個數值,現在又一個起始位置和終止位置,請找出一個從起始位置到終止位置代價最小的路徑:
1、只能沿上下左右四個方向移動
2、總代價是沒走一步的代價之和
3、每步(從a,b到c,d)的代價是c,d上的值與其在a,b上的狀態的乘積
4、初始狀態為1每走一步,狀態按如下公式變化:(走這步的代價%4)+1。
- 輸入:
-
第一行有一個正整數n,表示有n組資料。
每組資料一開始為6*6的矩陣,矩陣的值為大於等於1小於等於10的值,然後四個整數表示起始座標和終止座標。
- 輸出:
-
輸出最小代價。
- 樣例輸入:
-
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 5 5
- 樣例輸出:
-
23
BFS程式碼:
#include <iostream> #include <queue> using namespace std; struct Node { int x, y, sum, statu; }; int ans; int map[6][6]; int opt[6][6][4]; //記錄最優解,剪枝條件。4中狀態都要記錄 Node start; int ex, ey; int cnt = 0; int dir[4][2] = {{ 0, 1 },{ 1, 0 },{ 0, -1 },{ -1, 0 } }; queue<Node> q; void bfs(Node n) { q.push(n); int tempx, tempy, cost; while (!q.empty()) { cnt++; Node tn = q.front(); q.pop(); for (int i = 0; i < 4; i++) { tempx = tn.x + dir[i][0]; tempy = tn.y + dir[i][1]; if (tempx >= 0 && tempx < 6 && tempy >= 0 && tempy < 6) { cost = tn.statu * map[tempx][tempy]; //如果這一步比以前的某一步代價還大 或者 比到終點的代價還大 if (tn.sum + cost < opt[tempx][tempy][cost % 4 ] && tn.sum + cost < opt[ex][ey][cost % 4 ]) { opt[tempx][tempy][cost % 4] = tn.sum + cost; Node temp; temp.x = tempx; temp.y = tempy; temp.sum = tn.sum + cost; temp.statu = cost % 4 + 1; q.push(temp); } } } } } int main() { int k; cin >> k; while (k--) { for (int i = 0; i < 6; i++) for (int j = 0; j < 6; j++) { cin >> map[i][j]; for(int k=0; k<4; k++) opt[i][j][k] = 100000; } start.sum = 0; start.statu = 1; ans = 100000; cin >> start.x >> start.y >> ex >> ey; bfs(start); for (int i = 0; i < 4; i++) { if (ans > opt[ex][ey][i]) ans = opt[ex][ey][i]; } //cout << cnt << endl; cout << ans << endl; } return 0; }
Language:
C++
Result:
Accepted
Time:10
ms
Memory:1516
kb
DFS程式碼;
#include <iostream> using namespace std; int map[6][6]; int sx,sy,ex,ey,ans; int cnt = 0; int dir[4][2] = { {0,1},{1,0},{0,-1},{-1,0} }; bool visit[6][6]; void dfs(int x,int y,int sum,int statu){ cnt ++; if(sum < ans){ if(x == ex && y == ey){ ans = sum; return; } for(int i=0; i<4; i++){ int tempx = x + dir[i][0]; int tempy = y + dir[i][1]; if(visit[tempx][tempy] && tempx >=0 && tempx < 6 && tempy >=0 && tempy < 6){ int cost = statu * map[tempx][tempy]; visit[tempx][tempy] = false; dfs(tempx, tempy, sum+cost, cost % 4 + 1); visit[tempx][tempy] = true; } } } } int main() { int k; cin >> k; while(k--){ for(int i=0; i<6; i++) for(int j=0; j<6; j++){ cin >> map[i][j]; visit[i][j] = true; } cin >> sx >> sy >> ex >> ey; ans = 1000000; dfs(sx,sy,0,1); //cout << cnt << endl; cout << ans << endl; } return 0; }
Language:
C++
Result:
Accepted
Time:10
ms
Memory:1512
kb