POJ 1321 棋盘问题(深度优先搜索)

问题描述:输入n,k,n为n*n的棋盘格矩阵,其中#代表可放棋子位置,k为要放的棋子数,棋子不能出现在同行同列,求摆放的方案数。

解题思路:逐行放棋子(保证了不会在同行),每一行从第0列开始放棋子,不和前面的同列则为可行,从下一行开始递归。

代码如下:

#include<iostream>
#include<string.h>
using namespace std;
int way=0;
int n, k;
char a[100][100];
int visit[100];
int cnt=0;
void dfs(int h)
{
	if (way == k)
	{
		cnt++;
		return;
	}
	if (h > n)
		return;
	for (int i = 0;i < n;i++)
	{
		if (!visit[i] && a[h][i] == '#')
		{
			visit[i] = 1;
			way++;
			dfs(h + 1);
			visit[i] = 0;//第一种方案放完后,这颗树继续往下递归了,然后i还是回到前一个
			way--;//结点往后寻找下一个方案,因此相当于这颗棋子没放,way--,标记也要
		}//取消。
	}
	dfs(h+1);//如果这一行并没有可行的位置,可是还要继续搜索下一行,如果这一行放了也相当
}//于没放,从下一个位置开始搜索下一个方案。
int main()
{
	while (cin >> n >> k)
	{
		if (n == -1 && k == -1)
			break;
		for (int i = 0;i < n;i++)
			for (int j = 0;j < n;j++)
				cin >> a[i][j];
		cnt = 0;
		memset(visit, 0, sizeof(visit));
		dfs(0);
		cout << cnt << endl;
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值