题目:
N皇后问题 |
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) |
Total Submission(s): 568 Accepted Submission(s): 332 |
Problem Description 在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。 你的任务是,对于给定的N,求出有多少种合法的放置方法。 |
Input 共有若干行,每行一个正整数N≤10,表示棋盘和皇后的数量;如果N=0,表示结束。 |
Output 共有若干行,每行一个正整数,表示对应输入行的皇后的不同放置数量。 |
Sample Input 1 8 5 0 |
Sample Output 1 92 10 |
Author cgf |
Source 2008 HZNU Programming Contest |
Recommend lcy |
题目分析:
这道题是N皇后问题。所谓的N皇后问题无非是在一个N*N的棋盘上,摆放N个棋子。每个棋子两两不在同一行、同一列、同一斜线上。需要注意的是,在这道题中只开了一维数组map[]用来存储棋子的拜访情况。也就是在某一维中,他已经限定死了其摆放情况(如这道题中第i个棋子就必然放在第i行)。
代码如下:
/* * f.cpp * * Created on: 2015年2月25日 * Author: Administrator */ #include <iostream> #include <cstdio> using namespace std; const int maxn = 11; /** * map[]:用来存储第k个期指放在第几列. * 需要注意的是map[k]=j。表示的是第k个棋子放在第j列. * 同时,它在第k行 */ int map[maxn]; bool visited[maxn];//用於标记某一列是否已经访问过 int result[maxn];//打表,保存各个结果 bool flag;//用于标记某一个棋子是否成功 int n; int ans;//n为某一具体值时,棋子摆放的方案数 /** * 深搜. * k:表示目前放到了第几个棋子 */ void dfs(int k) { if (k == n + 1) {//如果k已经达到n+1.表示所有棋子已经摆放完毕 ans++;//棋子成功拜访的方案数+1 return; } int i; int j; for (i = 1; i <= n; ++i) {//遍历所有列 if (visited[i] == false) {//如果该列没有被访问 map[k] = i;//尝试将第k个棋子放在第i列(第k个旗子肯定是在第k行的) flag = true;//比尝试标记为成功 for (j = 1; j <= k - 1; ++j) {//遍历之前的k-1个棋子 /** * 如果他们在同一斜线上(在这种实现方式中,他已经确保了没一个棋子肯定会与其他棋子在不同行、不同列. * 这时候我们只需要判断一下它们是否在同一斜线上即可) */ if (abs(map[k] - map[j]) == abs(k - j)) { flag = false;//将标记设置为false break; } } if (flag == true) {//如果flag为true,表示第k个棋子可以摆放成功 visited[i] = true;//将第i列标记为已经访问过 dfs(k + 1);//开始拜访第k+1棋子 visited[i] = false;//将第i列重新标记为未访问过.用于其他情况 } } } } int main() { int i; /** * 打表各种情况 */ for (i = 1; i <= 10; ++i) { memset(visited, false, sizeof(visited)); flag = false; n = i; ans = 0; dfs(1); result[n] = ans; } while (scanf("%d", &n) != EOF, n) { printf("%d\n", result[n]); } return 0; }
(hdu step 4.3.6)N皇后问题(使用DFS来解决)
原文:http://blog.csdn.net/hjd_love_zzt/article/details/43938679