<基本> <背面>エイトクイーン問題

1.Intro

これは、1848年に国際的なチェスプレーヤーのマークが提起した質問です。8つのチェスクイーンの8×8グリッド上に配置され、それはお互いを攻撃することができない、すなわち、任意の二つのクイーンは、同じ行の同じ列または同じスラッシュであって、どのように多くの振り子方法を尋ねたことはできません。当社のコンピュータプログラミングは、この問題を解決します。

2.Solution

まず放棄し、その巨大な、状態空間8 ^ 8で、8サイクルを入れ子に、暴力的な直接法を試してみてください。

少し考えて、あなたはオーストリアを解決するためにバックトラッキングを使用することができます。

バックトラックバックトラックと言います

 

= []結果
DEFのFuc(パス選択リスト):
  終了条件が満たされている場合:
    (パス)result.add
  
  選択リストに選択のために:
    選択する
    のFuc(パス選択リスト)
    選択解除を

 

戻る再帰呼び出しを選択解除した後、再帰的で循環のための再帰、再帰的なメーク選択肢の前に、と。

8つのクイーン問題を解決するためにバックトラックを使用しようとすると、書き込みコード:

#include <ビット/ STDC ++ H>
 使用して 名前空間STDを、
短い ARR [ 8 ]。
int型の結果= 0 ;
BOOLのisValid(int型のx、int型のY){
     もし(x == 0 ){
         リターン 1 
    } 

    ためINT iは= 0 ; I <X; I ++ ){
         場合(ARR [I] == Y | ABS(ARR [I] -y)== ABS(I- X)){
             戻り 0 
        } 
    } 
    リターン 1 
} 
    
のボイドFuc(int型COL){
     場合(COL == 8 ){ 
        結果 ++ リターン; 
    } 
    
    ためINT iが= 0 ; I < 8 ; I ++ ){
         場合(はisValid(COL、I)){ 
            ARR [COL] = I。
            Fuc(COL + 1 )。
        } 
    }         
} 
int型のmain(){ 
    のFuc(0 )。
    coutの <<結果<< てendl;
    リターン 0 ; 
}

上記のコードでは、我々は問題を解決するために、このようなアイデアを守る:0列を見て、最初の列を見て、七時まで最初の2つの列を見て。各列の上に女王を置きます。

ARR [8]はケースに配置され、基板のアレイを示し、例えば、ARR [3] = 6クイーン(3,6)の位置があることを示しています。

結果は、可能な実施形態++の後に結果が判明したときに、カウント変数です。

isValid(int型のx、int型のy)の関数は、前の意志競合列の女王列のX位置(x、y)は、x-1かどうかを確認する時間を決定するために使用される、戻るを入れないで、リターンを置くことができ0 ;

Fuc(INT COL)関数は、最初のCOL列が時間の状況を参照して表す、本体です。

 また、それは確かに再帰的な速度を使用して速いと考えることができないので、それはサブ問題を最適化することができ、重複DPのようではありませんしながら、実際にはバックトラッキングアルゴリズムは、ブルートフォース、複雑度の高いと考えることができ、ここから見ることができます。

 emmm ------一時的にちょうどこの種のソリューションを書き戻したい、将来はおそらく、他のバーに展開されます。

3.Extension

まあ、Nクイーン問題への昇進に続いて実行可能なソリューション八のクイーンズを、見つけるために。

8限り、上記のコードは、すべてのn Jiuhaolaを交換するように

おすすめ

転載: www.cnblogs.com/dynmi/p/12128747.html