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的值,然後四個整數表示起始座標和終止座標。
-
輸出:
-
輸出最小代價。
-
範例輸入:
-
11 1 1 1 1 11 1 1 1 1 11 1 1 1 1 11 1 1 1 1 11 1 1 1 1 11 1 1 1 1 10 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