杭州エレクトリック - 2553 Nクイーン問題

 

問題やアイデアの意味

質問の意味:例えば、8つのクイーン問題で、8×8つの正方形は、8人の女王を置きます。女王はなく、同じ行ではなく、同じ列のではなく、同じ接続上の要件ではありません。

アイデア:アカウントに各列の各行を取ることの問題の完全な配列として見ることができるN、Nクイーン問題でほんの少しの改善を達成することができる唯一の女王を有することができます。アプローチはシンプルで、各2人の女王の合法性を決定するために順列の数を取得するたびに、このアプローチは最適ではありません。いっそのこと、あなたは女王インデックスの最初の行を配置するたびに、不正な操作がフォローアップの多くは、実行する必要がない場合は、場所は、すでに違法であるかどうかを判断バックに類似するが、これは少し異なっています。正当な場合には、追加、再帰的に実行し、次の行の振り子の法則の問題の女王。

そう、彼は簡単に無限ループを考えて、自分自身を納得させるかもしれない、いくつかの再帰の深い理解を達成するためにバックトラックの再帰8つのクイーン問題:ピットを辞任しました。次にウェルれて格納されているN-クイーン問題を有している、問題はすでに解決されるような8つのクイーンは、それがメモリに格納されるいくつかの領域を開くために少し必要がある[n]をメモリ部次回に直接出力することができます。トスされていない場合、それはなりますTLEアップ。

 

コード

#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;
}

 

おすすめ

転載: www.cnblogs.com/kyrie211/p/11273868.html