九度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
", 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
",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
", min);
84      }
85 
86     return 0;
87 }
原文地址:https://www.cnblogs.com/jasonJie/p/5694170.html