昔ながらのすべてのもの。ただ、自分のアイデアの下でこれを書いて仕上げ。なるほど、8つのクイーン問題を知らないBaiduのライブラリを
分析1:
競合しない対角、垂直、水平とは何ですか?最初の二つは、理解しやすいです。それは対角線?これは、形成されたクイーンスロープのいずれか2つが1または-1であることができない数学的なライン(2行)位置に変換されます。
ボード全体を横断するには?最も簡単なのは、各ラインを通って歩いて8つの重いループです。そして、重いサイクルの各カラムに通して流用。
アナログ場所:0番目の行を横断し、最初の場所は、(0,0)の位置は、セキュリティを決定します。
最初の行を横断する、それが安全でない、(1,0)に配置されます。配置(1,1)、又は安全でありません。配置(1,2)、セキュリティ。
二行目のトラバース。。。。。
安全ではない、安全とは何ですか?セキュリティのニーズが評価され、女王は以前に配置されているかどうかを決定します。それは女王が置かれていているので、あなたは女王を保存するためのデータ構造を選択する必要があります。二次元配列または何?それぞれの行だけの女王を置くことができるので、限り、我々が行に知っているように、列はOKに女王を置きました。整数配列INTに対応する[]、十分である(即ち、添字は行、列の値を示している。女王[行] = COL、行がクイーンを配置行COL列を示します。)。行は、B列は女王を置かれたとき、見つかった場合は、次の条件を満たす。彼らは安全ではないと考えられています。
データ構造がint []は、ピアのための前提条件ではない採用することができるので、1対応はできません。判断の必要性を排除。
2 = bで任意COL [行] = COL同じカラム、クイーンことができません。
3傾斜させることができない、女王[行] = COL任意(COL-B)/(行A)1または(COL-B)/(行A)= = - 1;
コードは以下の通りであります:
/// <要約> ///は、行の安全の列かどうかを判定する。/// </要約> /// <PARAM NAME = "A"> 行</ PARAM> /// <PARAM NAME = "B"> 列</ PARAM> /// <戻り値> </戻り> 公衆BOOL IsSafe(int型、int型 B) { ための(int型の列= 0、行<;行++)// 行の前面を横断、戻されません。トラバースする必要がありません。 { IF(B ==クイーン[行])// 同じ列 { リターンfalseに、
(B -行|| B - -クイーン[行] ==行-クイーン[行]は== A)// 斜列
{
戻り 偽を。
}
}
戻り 真。
}
配置機能:
公共 ボイド PlaceQueen_For()
{
ため(int型 COL0 = 0 ; COL0 < 8。 ; COL0 ++)// 各行スルーを、カラム0
{
IF(IsSafe(0、COL0))//
{
クイーン[ 0 ] = COL0; // 安全な位置記憶アップ、のための(INT COL1 = 0 ; COL1 < 8。 ; COL1 ++)// 最初の行の各列を通る1。 { IF(IsSafe(1、COL1)) {
女王[ 1 ] = COL1。
用(INT COL2 = 0 ; COL2 < 8 ; COL2 ++)
{
場合(IsSafe(2、COL2))
{
クィーン[ 2 ] = COL2。
用(INT COL3 = 0 ; COL3 < 8 ; ++ COL3)
{
場合(IsSafe(3、COL3))
{
[クイーン3 ] COL3 =。
用(INT COL4 = 0 ; COL4 < 8 ; COL4 ++)
{
場合(IsSafe(4、COL4))
{
クイーン[ 4 ] = COL4。
用(INT = COL5 0 ; COL5 < 8 ; COL5 ++)
{
場合(IsSafe(5、COL5))
{
女王[ 5 ] = COL5。
用(INT COL6 = 0 ; COL6 < 8 ; COL6 ++)
{
場合(IsSafe(6、COL6))
{
クイーン[ 6 ] = COL6。
用(INT = COL7 0 ; COL7 < 8 ; COL7 ++)
{
もし(IsSafe(7、COL7))
{
クイーン[ 7。 = COL7];
VARのA =(INT [])Queen.Clone(); // 現在の配置方法のクローンコピー。
List.Add(A); // リストの一覧<整数[]>構造。成功した配置方法は、ソリューションを保存するために使用されます。
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
分析:上記溶液が答えを解決することができましたが。しかし、スケーラビリティはかなり貧弱です。女王が10の場合、12女王はいますか?さらに、我々はFORループのそれぞれが非常に似ていることがわかりました。再帰を使用しての可能性?
次のように抽出された上記巡回符号
/// <まとめ> /// 排出ラインクイーン。/// </要約> /// <PARAM NAME = "行"> の行</ param>の公共無効 PlaceQueen(int型の行) { IF(ROW> =サイズ)// 成功したソリューション。Nは、安全な女王を置いています。(サイズは、初期クイーンNである) { // レコード配置方法。INT [] cloneQueen =(INT [])Queen.Clone(); List.Add(cloneQueen); リターン ; } ための(int型 COL = 0、COL <サイズ; COL ++)// の各列をループ {
もし(IsSafe(行、列))
{
クイーン[行] = COL。
PlaceQueen(行+ 1)。
}
}
}
ファイル名を指定して実行PlaceQueen(0)ランタイムソリューションを得ることができます。
前の二つの方法を通じて。これは、実際に新しい名前です。N> 12の場合。少し遅い計算。いくつかの最適化を図ることができます。このような対称性の使用など、それは半分に削減された数を横断します。
実際には、この機能は多くのことを最適化されています。2次元アレイを用いて、データ記憶構造の女王を有していました。IsSafe()関数は、より複雑です。
三つの分析
上記の機能は、より多くの時間は、我々はより低い消費の理由を参照してください。それは、すべてのソリューションをチェックしているので、確かに我々はn乗の数nを通過する必要があります。しかし、それぞれの時間はIsSafe()関数を決定するために必要です。IsSafe()関数の最適化が(クイーンのみ配置決定します。)。本当に一人ひとりの時間を必要とするかを決定する必要がありますか?クイーンズは、行COL列に列を配置します。次いで、行+ 1行COL-1、COL、COL + 1を取り戻すことができません。行+ 2行COL-2、COL、COL + 2はそうで取り戻すとすることができません。
これらの位置は、前処理ならば取り戻すことができます。だから、IsSafe()関数は完全にその不要な存在。各行は、すでに事前に知っていた位置を保持することができます。
牛が遊んでいた:基準源の女王のNビット演算バージョン http://www.matrix67.com/blog/archives/266
コードのC#のバージョン
プライベート 静的な int型 upperlim =(1 << 8) - 1 ; // 1111 1111 プライベート静的int型の合計= 0 ; パブリック静的ボイドテスト(int型の列、int型の LD、int型 RD) { 場合(行= upperlim!) { int型 POS = upperlim&〜(行| LD | RD)。しばらく(!POS = 0) { int型のp = POS&-pos。// 取最近一个可放位置。
POS = POS - P; // 残りの位置を置くことができます。
テスト(行+ P、(P + LD)<< 1。 、(RD + P)>> 1。);
}
}
他
{
SUM ++;
}
}
正直に言うと、読みやすさのビット・コンピューティング・バージョンは本当に高いではありません。しかし、問題に対処するため、このような「データ構造」を見つけるN-クイーン問題のために。本当にあまりにも悪いです。
その他の参照:http://www.cnblogs.com/jillzhang/archive/2007/10/21/922830.html
ます。https://www.cnblogs.com/xinjian/archive/2011/10/10/2206498.htmlで再現