利用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】深度優先搜索遞歸方式講解

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