百炼-1321-棋盘问题-C语言-递归算法

描述:
在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。
输入:
输入含有多组测试数据。每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目。 n <= 8 , k <= n,当为-1 -1时表示输入结束。随后的n行描述了棋盘的形状:每行有n个字符,其中 # 表示棋盘区域, . 表示空白区域(数据保证不出现多余的空白行或者空白列)。
输出:
对于每一组数据,给出一行输出,输出摆放的方案数目C (数据保证C<2^31)。

/************************************************************
**文件名:百炼-1321
**Copyright (c) 2015-2025 OrdinaryCrazy
**创建人:OrdinaryCrazy
**日期:20170809
**描述:百炼1321参考答案
**版本:1.0
*************************************************************/
#include <stdio.h>
#include <string.h>
char board[8][9];
int num,n,occupied[8];//记录列的占用情况
/*************************************************************
首先分析这个问题的状态有两个:
还有多少棋子要放上去,棋盘目前的情况,
这里需要注意的是有这样一种情况会造成重解,
你和你后面的那位刚好仅仅互换了位置
所以出现隐藏状态:现在的第一个棋子要从哪一位开始放
注意与八皇后中类似的行列检验方法,提高速度的关键
**************************************************************/
/*************************************************************
**函数名:solve
**输入:k-还有多少个棋子需要填入,a-可以填入的最优先位置的行
**功能:搜索将k个棋子填入(a,0)以后位置的所有可行解
**作者:OrdinaryCrazy
**日期:20170809
**版本:1.0
**************************************************************/
void solve(int k,int a)
{
    if(k == 0)//找到了一种解
    {
        num++;
        return;
    }
    int i,j;
    for(i = a;i < n;i++)
        for(j=0;j < n;j++)
            if(board[i][j] == '#' && !occupied[j])//找到了一个合适的位置
            {
                    occupied[j] = 1;
                    if(i != n-1)solve(k-1,i+1);
                    else if(k == 1) num++;
                    occupied[j] = 0;
            }
}
int main()
{

    int k,i;
    scanf("%d%d",&n,&k);
    while(n+1)
    {
        for(i = 0;i < n;i++)
            scanf("%s",board[i]);
        num = 0;
        memset(occupied,0,sizeof(occupied));
        solve(k,0);
        printf("%d\n",num);
        scanf("%d%d",&n,&k);
    }
    return 0;
}

    原文作者:递归算法
    原文地址: https://blog.csdn.net/OrdinaryCrazy/article/details/77017920
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞