九度oj 题目1091:棋盘游戏
- 题目描述:
-
有一个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
做这个题需要用到深度优先搜索或广度优先搜索
对于深度优先搜索而言,其基本思路是从起始点出发,遍历4个方向,一直走下去,直到终点。但要注意如何去剪枝。这里把花费作为参数传入到函数中,作为剪枝的条件。代码如下1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <string> 5 #include <cmath> 6 #include <algorithm> 7 #define inf 0x3f3f3f3f 8 9 int graph[6][6]; 10 int dir[4][2] = { {0,1},{1,0},{0,-1},{-1,0} }; 11 bool isVisit[6][6]; 12 13 int startx, starty, endx, endy; 14 int ans; 15 16 void dfs(int nowx, int nowy, int state, int sum) { 17 if(sum > ans) { 18 return; 19 } 20 if(nowx == endx && nowy == endy) { 21 ans = sum; 22 } 23 for(int i = 0; i < 4; i++) { 24 int tempx = nowx + dir[i][0]; 25 int tempy = nowy + dir[i][1]; 26 if(tempx >= 0 && tempx <= 5 && tempy >= 0 && tempy <= 5 && isVisit[tempx][tempy] == false) { 27 int cost = state * graph[tempx][tempy]; 28 int stateNext = (cost%4) + 1; 29 isVisit[tempx][tempy] = true; 30 dfs(tempx, tempy, stateNext, sum + cost); 31 isVisit[tempx][tempy] = false; 32 } 33 34 } 35 } 36 37 int main(int argc, char const *argv[]) 38 { 39 40 int n; 41 //freopen("input.txt","r",stdin); 42 scanf("%d",&n); 43 while(n--) { 44 for(int i = 0; i < 6; i++) { 45 for(int j = 0; j < 6; j++) { 46 scanf("%d",&graph[i][j]); 47 isVisit[i][j] = false; 48 } 49 } 50 scanf("%d %d %d %d",&startx, &starty, &endx, &endy); 51 ans = inf; 52 dfs(startx, starty,1,0); 53 printf("%d\n", ans); 54 } 55 56 return 0; 57 }
对于广度优先搜索,需要一个队列将每一层可以到达的点加入到队列中,每一个个点最多只有4种状态。我们用一个数组存这四种状态中每一种状态的最小代价,遍历到终点时四种代价之中的最小者则为最小花费
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <string> 5 #include <cmath> 6 #include <algorithm> 7 #include <queue> 8 #define inf 0x3f3f3f3f 9 using namespace std; 10 11 int graph[6][6]; 12 int dir[4][2] = { {0,1},{1,0},{0,-1},{-1,0} }; 13 int opt[6][6][5]; 14 15 int startx, starty, endx, endy; 16 int ans; 17 18 struct Node 19 { 20 int x; 21 int y; 22 int state; 23 int cost; 24 }; 25 26 queue <Node> Q; 27 28 void bfs(Node start) { 29 Q.push(start); 30 31 int tempx, tempy, cost; 32 while(!Q.empty()) { 33 Node now = Q.front(); 34 Q.pop(); 35 for(int i = 0; i < 4; i++) { 36 tempx = now.x + dir[i][0]; 37 tempy = now.y + dir[i][1]; 38 if(tempx >= 0 && tempx <= 5 && tempy >= 0 && tempy <= 5) { 39 cost = now.state * graph[tempx][tempy]; 40 int nextState = cost % 4 +1; 41 if(now.cost + cost < opt[tempx][tempy][nextState] && now.cost + cost < opt[endx][endy][nextState]) { 42 opt[tempx][tempy][nextState] = now.cost + cost; 43 Node add; 44 add.x = tempx; 45 add.y = tempy; 46 add.state = nextState; 47 add.cost = now.cost + cost; 48 // printf("%d %d %d\n",tempx, tempy, add.cost); 49 Q.push(add); 50 } 51 } 52 } 53 } 54 } 55 56 int main(int argc, char const *argv[]) 57 { 58 59 int n; 60 freopen("input.txt","r",stdin); 61 //freopen("output.txt","w",stdout); 62 scanf("%d",&n); 63 while(n--) { 64 for(int i = 0; i < 6; i++) { 65 for(int j = 0; j < 6; j++) { 66 scanf("%d",&graph[i][j]); 67 for(int k = 1; k <= 4; k++) { 68 opt[i][j][k] = inf; 69 } 70 } 71 } 72 scanf("%d %d %d %d",&startx, &starty, &endx, &endy); 73 ans = inf; 74 Node start; 75 start.x = startx, start.y = starty,start.state = 1, start.cost = 0; 76 bfs(start); 77 int min = inf; 78 for(int i = 1; i <= 4; i++) { 79 if(min > opt[endx][endy][i]) { 80 min = opt[endx][endy][i]; 81 } 82 } 83 printf("%d\n", min); 84 } 85 86 return 0; 87 }