UVA - 11214Guarding the Chessboard守卫棋盘(迭代加深搜索)

题意:输入一个n*m棋盘(0<n,m<10),某些格子有标记。用最少的皇后守卫所有带标记的格子。皇后规则是所在坐标的直线和斜线都可以被守卫,长度不限。

分析:因为不知道深度,所以用迭代加深搜索,判断条件可以参照之前写的八皇后问题。

具体就是回溯二分。

# include<iostream>
# include<cstdio>
# include<cmath>
# include<map>
# include<queue>
# include<string>
# include<string.h>
#include<set>
#include<list>
# include<algorithm>
using namespace std;
int row, col;
int maxd;
char mp[10][10];
int vis[4][30];
bool judge() {
	for (int i = 0; i < row; i++)
		for (int j = 0; j < col; j++)
			if (mp[i][j]=='X' && !vis[0][j] && !vis[1][i] && !vis[2][i + j] && !vis[3][j - i + 10])return false;
	return true;
}
bool dfs(int cur,int count0) {
	if (count0 == maxd) {
		if (judge()) {
			return true;
		}
		else return false;
	}
	else {
		for (int k = cur; k < row*col; k++) {
			int i = k / col;
			int j = k % col;
			int n1 = vis[0][j]; int n2 = vis[1][i]; int n3 = vis[2][i + j]; int n4 = vis[3][j - i + 10];
			vis[0][j] = vis[1][i] =  vis[2][i + j] = vis[3][j - i + 10] = 1;
			if (dfs(k, count0 + 1))return true;
			vis[0][j] = n1; vis[1][i] = n2; vis[2][i + j] = n3; vis[3][j - i + 10] = n4;
		}
	}
	return false;

}
	
int main() {
	string x; int kase = 0;
	while (scanf("%d", &row)&&row) {
		scanf("%d", &col);
		memset(mp, 0, sizeof(mp));
		memset(vis, 0, sizeof(vis));
		for (int i = 0; i < row; i++) {
			cin >> mp[i];
		}
		for (maxd = 0;; maxd++) {
			memset(vis, 0, sizeof(vis));
			if(dfs(0,0))break;
		}
		printf("Case %d: %d\n", ++kase, maxd);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_36973725/article/details/84900609