棋盘问题

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

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

  1. 样例输出

2
1

  1. 思路
    深度优先搜索,从第一行遍历至最后一行。判断是否满足输入的要求。对于每一个有效棋盘位置有放置与不放置两种选择。
  2. 代码(c++)
#include<bits/stdc++.h>
using namespace std;

int n , k ;
char a[9][9] ;//储存输入数据
int tmp[9][9] ;//标记有效棋盘 -1为无效位置 0为有效位置未摆放棋子 1摆放棋子
int ans = 0 ;

void dfs(int N , int K ){//从第N行开始 摆K个棋
	if( K == 0 ){//临界条件
		ans ++ ;
		return ;
	}


	if(N == n){//临界条件
		if(K != 1 ) return  ; //到最后一行时K大于一显然不符合
		for(int i = 1 ; i <= n ; i++){//对于最后一行每个能摆放的位置都是一种解法
			if(tmp[n][i] == 0 ){
				ans++ ;
			}
		}
		return ;

	}

	for(int i = 1 ; i <= n ; i++){//这一行摆琪
		if(tmp[N][i] ==  0 ){
			for(int j = 1 ; j <= n ; j++ ){
				if(tmp[j][i] == 0 ) tmp[j][i] = 1 ;
			}
			dfs(N+1,K-1) ;
			for(int j = 1 ; j <= n ; j++ ){
				if(tmp[j][i] == 1 ) tmp[j][i] = 0 ;
			}
		}
	}
	//这一行不摆棋子
	dfs(N+1,K) ;

}

int main(){
	while(1){
		cin >> n >> k ;
		if(n == -1 && k == -1 ) break ;

		memset(tmp,-1,sizeof(tmp)) ;
		ans = 0 ;
		for(int i = 1 ; i <= n ; i ++){//输入
			for(int j = 1 ; j <= n ; j++){
				cin >> a[i][j] ;
				if(a[i][j] == '#') tmp[i][j] = 0 ;
			}
		}

		dfs(1,k);
		cout << ans << endl ;
	}
	return 0 ;
}

8.OJ

http://noi.openjudge.cn/ch0205/323/

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值