利用DFS(深度优先搜索)解决棋盘游戏

前言

很久都没有写过C++代码了,最近突然有个同学问我一个题目,觉得很有意思,是一个棋盘游戏,核心思想是使用DFS算法来遍历访问,寻找最小代价路径。

DFS算法简介:

DFS算法,Depth First Search,即深度优先搜索。

DFS算法思想:

DFS是一种用于遍历或搜索树或图的算法。首先以一个未被访问过的顶点作为起始顶点,沿当前顶点的边走到未访问过的顶点;当没有未访问过的顶点时,则回到上一个顶点,继续试探访问别的顶点,直到所有的顶点都被访问。
沿着某条路径遍历直到末端,然后回溯,再沿着另一条进行同样的遍历,直到所有的顶点都被访问过为止。

DFS算法过程:

1、任选一顶点作始点 v ,访问该顶点
2、沿深度方向,依次遍历 v 的未访问邻接点——直到本次遍历结束
3、一次遍历完时,若有未访问顶点:任选一个未访问顶点作起始点,GOTO第二步

棋盘游戏简介:

这个练习题目好像是上海交通大学某年计算机专业考研复试的上机题。
别人分享给我的链接是:https://www.nowcoder.com/practice/368c98c7bff54a30bba29ae1ba017d55?tpId=62&tqId=29455&tPage=1&ru=%2Fkaoyan%2Fretest%2F2002&qru=%2Fta%2Fsju-kaoyan%2Fquestion-ranking
链接来源于牛客网。

题目描述

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

输入描述

每组数据一开始为6*6的矩阵,矩阵的值为大于等于1小于等于10的值,然后四个整数表示起始座标和终止座标。

输出描述

输出最小代价。

C++代码分享:

#include<stdio.h>
#include<limits.h>
#include<iostream>
using namespace std; 
int matrix[6][6];
bool mark[6][6];
int a, b, c, d; //[a,b]起始点座标,[c,d]终止点座标
int go[4][2] = { 1,0,0,-1,-1,0,0,1 }; //向右,向下,向左,向上
int mincost=INT_MAX

void DFS(int i, int j, int stat, int total_cost)//[i,j]当前起始点座标,stat记录该点状态,cost记录当前总代价
{
	if(i==c&&j==d){
		if(total_cost < mincost){
			mincost = total_cost;
		}
		return ;
	}
	if(total_cost > mincost) 
 		return ;
	for (int k = 0; k < 4; k++)
	{
		int nx = i + go[k][0];
		int ny = j + go[k][1];  //计算下一个点座标
		if (nx < 0 || nx >= 6 || ny < 0 || ny >= 6)
			continue;                              
		if (mark[nx][ny] == false){    //判断是否已经在路径中
			mark[nx][ny] = true;
			int cost = matrix[nx][ny] * stat;      //该步代价
			int news = cost%4+1;              //该步状态
			DFS(nx, ny, news, total_cost+cost );
			mark[nx][ny] = false;
		}	
	}
}
int main()
{
	while (scanf("%d", &matrix[0][0]) != EOF)
	{
		for (int j = 1; j < 6; j++) scanf("%d", &matrix[0][j]);
		for (int i = 1; i < 6; i++)
			for (int j = 0; j < 6; j++)
				scanf("%d", &matrix[i][j]);
		scanf("%d%d%d%d", &a, &b, &c, &d);       //读入输入矩阵和起始、终止点座标
		for (int i = 1; i < 6; i++)
			for (int j = 0; j < 6; j++)
				mark[i][j] = false;              
		mark[a][b] = true;                      //mark初始化
		DFS(a, b, 1, 0);
		printf("%d\n", mincost);
	}
	return 0;
}

测试输入和结果:

示例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

示例2

输入:

2 8 1 8 6 8
2 4 7 2 6 5
6 8 6 5 7 1
8 2 9 9 7 7
9 9 9 5 2 2
6 1 1 4 6 4
4 1 4 1
输出: 0

参考资料

【DFS】深度优先搜索递归方式讲解

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章