バックトラッキング アルゴリズム - n クイーン問題

バックトラッキングアルゴリズムとは何ですか?
バックトラッキング方法は通常、次の問題を解決できます。
      組み合わせ問題、順列問題、部分集合問題、 チェス盤問題 など
n-クイーン問題はチェス盤の問題の 1 つです。
バックトラッキング法によって解決される問題は、N 分ツリーとして理解できるツリー構造に抽象化できます。
バックトラッキング手法では、再帰を使用してセット内のサブセットを再帰的に検索します。セットのサイズは、再帰を必要とする層として理解できます。
また、再帰を使用する場合は、終了条件が必要です。そうでないと、関数本体を終了できず、エラーが発生します。したがって、この N 分木には制限があります。
バックトラッキング アルゴリズムの流れ:
 
         1. バックトラッキング関数で入力されるパラメータと戻り値、関数本体です

         2. 終了条件; 再帰的であるため、終了条件が必要です

         3. コアバックトラッキングアルゴリズム

                 N 分木: (

                     for ループ: 水平方向にトラバースする

                      再帰: 垂直走査

                )

         4. 戻り値を出力する

これはバックトラッキング アルゴリズムの核となる紹介です

まずは質問を探してみましょう。

お役に立てましたら、高評価をお願いします!!    



トピックの要件

     n 個のクイーンをn*n個のチェス盤に配置し、互いに攻撃できないようにします。つまり、2 つのクイーンを同じ行、列、または対角線上に配置することはできません。配置する方法は何通りありますか?

     入力フォーマット:8

     出力フォーマット: 92

トピック分析

1. n クイーンのチェス盤には次のルールがあります

      1. 同じ回線上に存在することはできません

      2. 同じ列に入れることはできません

      3. 同じスラッシュ上に置くことはできません

通常、チェス盤の場合は 2 次元配列を使用します。

しかし、このゲーム ルールでは、各行に配置できるチェスの駒は 1 つだけであるため、1次元配列を使用しても問題ないことがわかります。

2.これら 3 つのルールに対して、コア層は 2 つの判断を行う必要があります (ライン上の問題を考慮せず、1 次元配列を使用)

      現在の列にクイーンを配置する準備をしているときは、次のことを判断する必要があります。   

     1. 現在のクイーンの位置は、以前に配置されたクイーンと同じ列にありますか? そうであれば、N 番目の列 (境界に達する)まで列を変更します。前のクイーンの行に戻って、位置を変更する必要があります。前の列のクイーンの列。

     2. 現在のクイーンの位置は、前に配置したクイーンと同じ傾斜(つまり 45° または 135° ) 上にありますか? そうであれば、N 番目の列 (境界に達する)まで列を変更し、前の位置に戻る必要があります。 row of queens. は、前の行のクイーンの列を変更します。

3.再帰処理における終了条件

     バックトラッキングアルゴリズムについて考えて、それを最も簡単な言葉で説明することができます。現在の道路が通行止めになったらどうするか、戻って前の場所に方向を変えるか、といったことです。

      終了条件は最初のステップに戻って最初のステップの最後の位置に到達したことじゃないですか? 仕方がないならそれで終わりです どうして行く先もないのに留まり続けるのですか? ハハハハ;

   

コード



#include<bits/stdc++.h> 

using namespace std;


int main(){
         int  n,sum=0;
         cin>>n;	
         int HANG= 0;//皇后个数,行数;	
         int LIE = 0;//皇后占据的列为;
         int queen[n] = {0};//储存皇后的位置,值为列;						
		
	  while(1){
		
        int AK = 0;		//攻击
		if(HANG== 1 && queen[0] == 7 && LIE == 7)break;//终止条件	
		  
		//判断是否在同一列,统一斜线
		for(int i=0;i<HANG;i++)
		{			
			if(queen[i] == LIE)AK = 1;	//同一列,攻击	
			if(HANG-i == queen[i]-LIE ||HANG-i == -(queen[i]-LIE) )AK = 1;//同一斜线,攻击					
		}
		  
		//判断可不可以放入
		if(AK == 0)
		{	//表示可以放置
			queen[HANG] = LIE;		
			HANG++;	LIE = 0;				
			if(HANG== 8)sum++;				    
		 }
	    else
		{			
			 LIE++;			
			 while(LIE>=8)
			 {	//回朔,上一个皇后往后移一格
			     HANG--;				
				 LIE = queen[HANG]+1;	
			 }
		}
   }
	cout<<sum<<endl;
	return 0;	
}

作成するのは簡単ではありません。コメントやメッセージを残すことを歓迎します。注意して、迷子にならないようにしてください。

作成するのは簡単ではありません。コメントやメッセージを残すことを歓迎します。注意して、迷子にならないようにしてください。

作成するのは簡単ではありません。コメントやメッセージを残すことを歓迎します。注意して、迷子にならないようにしてください。

おすすめ

転載: blog.csdn.net/weixin_59367964/article/details/127986711