2020-02-16

题目:在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。
Input输入含有多组测试数据。 每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目。 n <= 8 , k <= n 当为-1 -1时表示输入结束。 随后的n行描述了棋盘的形状:每行有n个字符,其中 # 表示棋盘区域, . 表示空白区域(数据保证不出现多余的空白行或者空白列)。
Output对于每一组数据,给出一行输出,输出摆放的方案数目C (数据保证C<2^31)。
Sample Input
2 1#…#4 4…#…#…#…#…-1 -1
Sample Output21
题解:深度优先搜索,dfs,棋子不能摆在相同的行和相同的列,所以可以依次枚举一行,然后标记每一列是否走过,再在此基础上进行dfs。#include<stdio.h>
#include<string.h>
#define TRUE 1
#define FALSE 0
#define MAX_N 8
#define BOARD TRUE
#define BLANK FALSEint board[MAX_N][MAX_N];// 棋盘,BOARD表示棋盘,BLANK表示空白
int n, k, solution;int row[MAX_N];// 每行是否有棋子,TRUE表示有棋子,FALSE表示无棋子
int column[MAX_N];// 每列…同上
void backTrack(int left, int x) {// 回溯,left表示剩余棋子,x表示当前行
if (left == 0) {// 无多余棋子
++solution;// 方案数加1
return; } // 遍历x行及下方的棋盘
for (int i = x; i < n; ++i) {
for (int j = 0; j < n; ++j) {
if (board[i][j] == BLANK) {// 空白不能放旗子

continue; }
if (row[i] == TRUE || column[j] == TRUE) {
// 行或列有棋子不能放棋子
continue; } // 当前位置可以放子,设为TRUE
row[i] = TRUE;
column[j] = TRUE; // 棋子数减1,行数加1
backTrack(left - 1, i + 1); // 复盘,设为无子
row[i] = FALSE;
column[j] = FALSE; } }}
int main() {
while (scanf("%d %d", &n, &k) && n != -1 && k != -1)
{ getchar(); // 输入棋盘
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
char ch = getchar();
if (ch == ‘.’) {
board[i][j] = BLANK; }
else if (ch == ‘#’) { board[i][j] = BOARD; } } getchar(); }
memset(row, FALSE, sizeof(row)); memset(column, FALSE, sizeof(column));
solution = 0;
backTrack(k, 0);// 回溯 printf("%d\n", solution); }
return 0;}

对于dfs(Depth First Search)深度优先搜索增加一道基础入门题,加深理解。
题目大意:假如有编号为1、2、3,的三张扑克牌和编号为1、2、3的三个盒子。现在需要将这三张牌分别放到三个盒子里面,并且每个盒子有且只能放一张扑克牌,问一共有几种不同的方法。这个问题很简单,用dfs算法实现,代码:
#include<stdio.h>
int a[10],book[10],n;
void dfs (int step)//step表示第几个盒子
{ int i; if(step== n+1)//如果第n+1个盒子,那么则表示第n个盒子已经放有扑克牌
{ for (i=1; i<=n; i++)
printf("%d",a[i]);//输出盒子中扑克牌的编号 printf("\n");
return; }
//此时第step个盒子按照1,2,3的顺序依次放
for(i=1;i<=n;i++) {
if(book[i] == 0) //判断牌i是否已经放在盒子中,若book[i]等于0,则表示第i张牌未放到盒子中 {
a[step]=i;//将i号牌放入到第step个盒子中
book[i] = 1;//将book[i]设为1,表示已经放入到盒子中。
//第step个盒子已经放好扑克牌了,现在要到下一个盒子仿牌
dfs(step+1);
book[i]=0;//把牌拿回来进行下一次尝试 } }
return; }
int main()
{
scanf("%d",&n);
dfs(1);//从一号盒子开始
getchar();getchar();
return 0;}

/* ********2020.2.6/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值