棋盘游戏

题目描述
有一个6*6的棋盘,每个棋盘上都有一个数值,现在又一个起始位置和终止位置,请找出一个从起始位置到终止位置代价最小的路径: 1、只能沿上下左右四个方向移动 2、总代价是没走一步的代价之和 3、每步(从a,b到c,d)的代价是c,d上的值与其在a,b上的状态的乘积 4、初始状态为1 每走一步,状态按如下公式变化:(走这步的代价%4)+1。

输入描述:
每组数据一开始为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

题目解析:还是一个回溯问题,从当前位置出发(每次走过的点需要记录已经走过了,不能再走),然后经过上下左右,(例如,先从上然后下一步可能走上,左,右),记录每次不同方案走到目标点的代价,比较记录出最小代价。

代码:

#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<string.h>
#include<iostream>
#include<vector>
#include<map>
#include<iomanip>
using namespace std; 
int ans =  0x3f3f3f3f;    //代价定义为最大数 
int matrix[6][6];
int x_1 , y_1 , x_2 , y_2;
int a[] = {-1,1,0,0};     //移动,只有四个移动,一行向左,向右,向上,向下 
int b[] = {0,0,1,-1};
int visit[6][6];         //记录此时是否使用了该点 

//深度遍历,从该点出发进行上下左右移动,直到到达最后目标点 
void dfs(int x,int y,int now,int status){    //xy当前位置,now代价,status状态 
	if(x == x_2 && y == y_2){        //如果当前点 == 结束点,输出最小代价 
		ans = min(ans , now);          //ans记录不同走法到达目标点后的最小代价 
	}
	visit[x][y] = 1;             //标记该点已经走过了 
	for(int i = 0; i < 4; i++){     
		int xx = x + a[i], yy = y + b[i];     //移动位置
		if(xx < 0 || xx > 5 || yy < 0 || yy > 5 || visit[xx][yy] == 1){   //超出棋盘范围,或者已经选过了 
			continue;   //跳出本次循环,此路不通。
		}
		int cost = matrix[xx][yy] * status;
		int new_status = (cost % 4) + 1;
		dfs(xx , yy , now + cost , new_status);   //继续走,直到到达目的地 
	}
	visit[x][y] = 0;
	
}
int main()
{
	for(int i = 0 ; i < 6; i++){
		for(int j = 0 ; j < 6; j++){
			cin >> matrix[i][j];
		}
	}
	memset(visit,0,sizeof(visit));   //初始化选中状态 
	cin >> x_1 >> y_1 >> x_2 >> y_2 ;
	dfs(x_1 , y_1 , 0 , 1);   //从目标地点出发,代价,状态
	cout << ans << endl;      // 输出最小代价 
	
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值