您的位置:首页 > 其它

九度[1091]-棋盘游戏

2017-09-09 17:04 246 查看

九度[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

解题思路:

用BFS和DFS都可以,就是需要注意剪枝,否则搜索空间过大。

AC代码:

#include <cstdio>
#include <queue>
#define LEN 6
using namespace std;
int n;
int dat[LEN][LEN], opt[LEN][LEN][4];
int moveX[4] = {0, 1, 0, -1}, moveY[4] = {1, 0, -1, 0};

struct node{
int x, y, value, cost;
}start, end;

bool isOK(node n, int type){
if(n.x + moveX[type] >= 0 && n.x + moveX[type] <= LEN-1 && n.y + moveY[type] >= 0 && n.y + moveY[type] <= LEN-1) return true;
else return false;
}

int findPath(node a, node b){
int min = 1000000000;
queue<node> que;
que.push(a);
node n;
while(!que.empty()){
n = que.front();
que.pop();
if(n.x == b.x && n.y == b.y) {
if(n.cost < min) min = n.cost;
continue;
}
for(int i = 0; i < 4; i++){
if(isOK(n, i)) {
node tmp = {n.x+moveX[i], n.y+moveY[i]};
int tmpCost = n.value * dat[tmp.x][tmp.y];
tmp.value = tmpCost % 4 + 1;
tmp.cost = n.cost + tmpCost;
if(tmp.cost < opt[b.x][b.y][tmp.value-1] && tmp.cost < opt[tmp.x][tmp.y][tmp.value-1]) {
opt[tmp.x][tmp.y][tmp.value-1] = tmp.cost;
que.push(tmp);
}
}
}
}
return min;
}

int main(){
freopen("C:\\Users\\Administrator\\Desktop\\test.txt", "r", stdin);
while(scanf("%d", &n) != EOF){
while(n--){
for(int i = 0; i < LEN; i++){
for(int j = 0; j < LEN; j++){
scanf("%d", &dat[i][j]);
for(int k = 0; k < 4; k++){
opt[i][j][k] = 1000000000;
}
}
}
scanf("%d%d%d%d", &start.x, &start.y, &end.x, &end.y);
start.value = 1;
start.cost = 0;
printf("%d\n", findPath(start, end));
}

}
fclose(stdin);
return 0;
}


参考链接
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: