棋盘问题-简单搜索练习

POJ1321(DFS棋盘问题)


解题报告:
1.题意很简单,一个棋盘问题,可以用搜索方式解决。那么好,它的搜索框架很明晰了,从一个状态到下一个搜索状态,直到数目达到K,计数加一,或者此搜索状态无解,回溯。

显然,搜索退出条件是数目达到K或者此搜索状态无解。


2.状态如何表示?

vis[i][j]标记是否有落子即可。再简单一点,采取按行搜索的顺序,在当前行row下,只需记录col[j]是否有落子即可。


3.状态如何转移?

在当前行row下,已经落子cnt,那么可以就当前行是否落子转移到下一个状态。

有两种可能,(1)要么不落子,直接搜索下一行row+1;(2)要么遍历所有列,可以落子则落子


//DFS
#include <cstdio>
#include <string>
#include <algorithm>
using namespace std;
const int maxn = 9;
bool col[9];
char map[9][9];
int N, K, ans;

bool dfs(int cnt, int row)				//cnt已落子数,row当前行数
{
	if (cnt == K) return true;
	if (row >= N) return false; 
	if (dfs(cnt, row + 1)) ans ++;		//该行不落子
	for (int j = 0; j < N; j++)			//如果条件允许该行落子
	{
		if (!col[j] && map[row][j] == '#')//允许条件,j列无子,棋盘可落子
		{
			col[j] = 1;
			if (dfs(cnt + 1, row + 1)) 
				ans ++;
			col[j] = 0;
		}
	}
	return false;
}

int main()
{
	while (scanf("%d%d%*c", &N, &K) != EOF && (N != -1 || K != -1))
	{
		for (int i = 0; i < N; i++)
			gets(map[i]);
		ans = 0;
		memset(col, 0, sizeof(col));
		dfs(0,0);
		printf("%d\n", ans);
	}
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值