棋盘问题大全(DFS)

本文通过两道棋盘问题介绍了如何利用DFS解决棋盘摆放问题和寻找最低花费路径。第一题要求在给定形状的棋盘上摆放棋子,避免同行或同列,通过DFS搜索并剪枝优化得到所有方案数。第二题涉及不同颜色棋盘的路径规划,需要考虑魔法格子的使用,同样使用DFS进行状态枚举和剪枝操作,求解最小金币花费。
摘要由CSDN通过智能技术生成

第一题:

大家看完这两道题应该对棋盘问题有了一定认识,并且对dfs有了更加深刻的认识!耐心看完,我写的十分详细。

题目:
不爱看题目这里有链接
在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。

要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放 k 个棋子的所有可行的摆放方案数目 C。

输入格式
输入含有多组测试数据。

每组数据的第一行是两个正整数 n,k,用一个空格隔开,表示了将在一个 n∗n 的矩阵内描述棋盘,以及摆放棋子的数目。当为-1 -1时表示输入结束。

随后的 n 行描述了棋盘的形状:每行有 n 个字符,其中 # 表示棋盘区域, . 表示空白区域(数据保证不出现多余的空白行或者空白列)。

输出格式
对于每一组数据,给出一行输出,输出摆放的方案数目 C

输入样例:

2 1
#.
.#
4 4
…#
…#.
.#…
#…
-1 -1

输出样例:

2
1

题意分析:

给出n*n的棋盘,其中’#‘可以放,’.'不可以放,给出棋子个数k,我们要找出所有棋子摆放情况!这种题第一时间肯定想到的就是搜索!找出所有可能。这道题的思想和"全排列"是差不多的,我们可以利用dfs深度优先搜索,通过剪枝优化,枚举所有状态。

如何找出深搜的终点呢?如何剪枝优化呢?

首先棋盘为n*n,我们先讨论剪枝优化,很容易想到,当棋子越出棋盘,这种情况肯定要剪掉,或者遇到’.'的情况我们也剪掉,我们在讨论dfs终点,也就是深搜到底的情况,这里我们用last变量,表示棋子剩余数量,所以当last为0时,也就是所有棋子都摆放完毕,这就是深搜的终点!

如何枚举所有状态呢?

一个棋子肯定要放在某行某列,那么放在第几行第几列就是他的状态,在枚举状态过程中,我们可以固定行,然后枚举j列,每次dfs带入行数,在dfs过程中枚举所有可以放的列,要注意,某一行也可不放置棋子!!!

代码实现:

#include <iostream>
using namespace std;
const int maxn=10;
char maps[maxn][maxn];//棋盘
int visit[maxn];//是否被标记
int n,ans,k;

void dfs(int x,int last)//last 剩余棋子数量,x为行数
{
   
    if(last==0)
    {
   
        ans++;
        return;
    }


    if(x>n)//越界
    {
   
        return ;
    }
    
    //第i行插入棋子情况
    for(int j=1; j<=n; j++)
    {
   
       if(maps[x][j]=='#'&&!visit[j]){
   
        visit[j]=1
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值