Problem D: 【递归入门】n皇后 问题(原始的8皇后问题)

Description

       会下国际象棋的人都很清楚:皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。如何将8个皇后放在棋盘上(有8 * 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题。


Input

一个整数n( 1 < = n < = 10 ) 

Output

每行输出对应一种方案,按字典序输出所有方案。每种方案顺序输出皇后所在的列号,相邻两数之间用空格隔开。如果一组可行方案都没有,输出“no solute!”

Sample Input Copy

4

Sample Output Copy

2 4 1 3
3 1 4 2

 

最终AC代码如下:

#include <bits/stdc++.h>
using namespace std;
int n, d[15]={0};
bool flag, vis[15];
//很重要的是一个思想是:d[index] = i; 即表示这个皇后放在(index, d[index])=>(index, i)位置上
//因此明白 数组d的下标即表示对应的行号! 
void DFS(int index){
    if(index == n+1){
        flag = false;
        for(int i=1; i<=n; i++) printf("%d%c", d[i], i==n?'\n':' ');
        return ;
    }
    for(int i=1; i<=n; i++){
        if(!vis[i]){ //表示这列可以可能可以放皇后 
            bool fg = true; //fg为ture表示找到一个非对角线的位置 
            for(int pre=1; pre<index; pre++){ //注意这里是 pre<index 而非pre<=n!!! 
                if(abs(index-pre) == abs(i-d[pre])){ //在对角线 放弃 
                    fg = false;
                    break;
                }
            }
            if(fg){
                d[index] = i;
                vis[i] = true;
                DFS(index+1);
                vis[i] = false;
            }
        }
    }
}
int main(){
    while(~scanf("%d", &n)){
        memset(vis, false, sizeof(vis));
        memset(d, 0, sizeof(d));
        flag = true; //标记是否找到 true 表示未找到 
        DFS(1);
        if(flag) printf("no solute!\n");
    }
    return 0;
}

总结:一维数组其实蕴含了两个维度的信息,即下标和对应下标数组存储的值。当题干条件中的某一维度可以视为线性增加时,是否可以想起数组的下标呢???一旦明白了数组就可以表示一个位置(即(index, a[index])),那么这题的思路就清晰了。但是如果首先想到的是一个坐标有两个维度,因此开一个二维数组进行标记......那么麻烦就大了。

posted @ 2020-04-09 10:09  已是夕阳,不如放下  阅读(397)  评论(1编辑  收藏  举报