杭电 -- 2553 N皇后问题

 

题意及思路

题意:例如在八皇后问题中,8*8的方格中,要求放置八个皇后。要求两两皇后均不在同一行,不在同一列,而且不在同一个连线上。ios

思路:考虑到每一行每一列只能有一个皇后,这就能够当作是n的全排列问题,只要稍加改进就能够实现n皇后问题。朴素的作法是,每一次获得一个排列数时,判断两两皇后之间是否合法,但这种作法并非最优的。更好的作法是,每次要放置第index行皇后时,判断该位置是否已经非法,若是非法则后续不少操做都不须要执行,相似于回溯,但这个又有点不同。若是合法,则添加,递归执行下一行的皇后摆法问题。spa

踩坑点:八皇后问题的递归回溯实现要对递归理解深刻一些,不然本身可能说服不了本身,思惟容易死循环。其次有一点,须要开辟一段空间,存放已经解决好的n个皇后的问题,如8皇后问题已然解决,就将其存入memory[n] 记忆单元去,下一次直接输出便可。若是不这样折腾,就会TLE了。code

 

代码

#include <iostream>
#include <cstdio>
#include <math.h>

using namespace std;

const int MAXSIZE = 100;
int n,P[MAXSIZE],cnt=0;
int memory[MAXSIZE] = {0};
bool hashTable[MAXSIZE] = {false};

void Nqueue(int index){
    if(index == n+1){
        cnt++;
        memory[n]++;
        return;
    }
    for(int x=1;x<=n;x++){ //第x列 
        if(hashTable[x] == false){ //第x列尚未皇后
            bool f = true; //f为true表示当前皇后不会和以前的皇后冲突
            for(int pre=1;pre<index;pre++){
                if(abs(index-pre) == abs(x-P[pre])){
                    f = false;
                    break;
                }
            }
            if(f){
                P[index] = x; //将当前index行的皇后放在x列上 
                hashTable[x] = true;
                Nqueue(index + 1); //处理下一行 
                hashTable[x] = false; //处理一个摆法完毕,递归回掉 
            }
        } 
    }
    
}

int main()
{
    std::ios::sync_with_stdio(false);
    cin.tie(0);
    while(scanf("%d",&n)!=EOF && n!=0){
        cnt = 0;
        if(memory[n]==0){
            Nqueue(1); //从第一行开始 
            cout << cnt << endl;
        }else
            cout << memory[n] << endl;            
    }
    return 0;
}
相关文章
相关标签/搜索