1.6.3 棋盘问题1

该博客讨论了一种棋盘放置问题,其中目标是在给定形状的不规则棋盘上放置棋子,确保任何两枚棋子不在同一行或同一列。博主使用了深度优先搜索(DFS)算法来解决这个问题,类似于经典的八皇后问题。示例输入和输出展示了不同尺寸棋盘的解决方案数量。
摘要由CSDN通过智能技术生成

Description

在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。
要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列。请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。

Input

输入含有多组测试数据。

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

当为−1−1时表示输入结束。

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

Output

对于每一组数据,给出一行输出,输出摆放的方案数目CCC。

Sample Input 1

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

Sample Output 1

2
1
//DFS
//类似于八皇后的一道多了一些限制的题

#include <cstdio>
#include <iostream>
#include <cstring>

using namespace std;

const int N = 20;

char g[N][N];                                       //存储输入棋盘 
int ans;                                            //存储答案 
int n, k;
int m;                                              //存储已近放入棋盘的棋子数 
bool line[N];                                       //存储当前列上有没有其他棋子 

void dfs(int x)
{
    if(m == k)                                      //当棋子放光的时候 
    {
        ans++;
        return;
    }

    if(x == n)                                      //防止越界 
        return;

    for(int i = 0; i < n; i++)                      //直接dfs简单完事 按着列的顺序依次向下
        if(!line[i] && g[x][i] == '#')
        {
            line[i] = true;
            m++;                                    //记录放入的棋子数 
            dfs(x + 1);
            line[i] = false;                        //还原初始状态 
            m--;
        }

    dfs(x + 1);                                     
    //这个是关键,因为 k <= m,因此可能有的行不能放棋子,所以我们要手动舍弃行,直接进入下一行,以免有的情况被遗漏
}

int main()
{
    while(scanf("%d%d", &n, &k) && n != -1 && k != -1)
    {
        ans = m = 0;
        for(int i = 0; i < n; i++)
            for(int j = 0; j < n; j++)
                cin >> g[i][j];

        dfs(0);
        cout << ans << endl;
    }

    return 0;
}

大家可以比划着自己手动模拟一下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

irrationality

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值