uva 11195(状态压缩+dfs)

题意:n皇后问题,'.'可以摆放,'*'不可以摆放,问有多少种摆法。

题解:普通做法会超时,要用到状态压缩,每行能摆的位置标记为0,不可以的地方标记为1,然后深搜,参数有当前行数,和列、左对角线、右对角线不可以摆放的位置标记数,然后把当前行所有可以摆放的位置都递归下去,计方法数。

#include 
const int N = 20;
int m[N], n, res, all;
char str[N];

void dfs(int cur, int c, int l, int r) {
	if (cur == n) {
		res++;
		return;
	}
	int now = ~(m[cur] | c | l | r);//取反后0为不可摆放位,1可以摆放
	int last = now & -now & all;//找到最后一个1
	while (last) {
		dfs(cur + 1, c | last, (l | last) << 1, (r | last) >> 1);//下一行的列、左、右不可摆放位标记
		now ^= last;//最后的1标记为0
		last = now & -now & all;//前一个1
	}
}

int main() {
	int cas = 1;
	while (scanf("%d", &n) && n) {
		all = (1 << n) - 1;
		for (int i = 0; i < n; i++) {
			m[i] = 0;
			scanf("%s", str);
			for (int j = 0; j < n; j++)
				if (str[j] == '*')
					m[i] |= (1 << j);//不可以摆放位置标记1
		}
		res = 0;
		dfs(0, 0, 0, 0);
		printf("Case %d: %d\n", cas++, res);
	}
	return 0;
}


你可能感兴趣的:(ACM-高效算法)