您的位置:首页 > 编程语言 > C语言/C++

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

2017-08-09 22:47 330 查看
描述:

在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放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] == '#' && !
4000
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: