NFSクイーンの問題DFSソリューション(2種類あります)

ACWINGボードの質問のアドレス:https ://www.acwing.com/problem/content/description/845/

質問で言われていることは非常に明確で、nクイーンとは何ですか。チェスの駒を配置するには、チェスの駒が置かれている列の対角線方向と反対の対角線方向にチェスの駒がないことを確認する必要があります。判断方法として、ブール型の行[]配列、行[i] = trueを導入します。これは、この列がすでにポーンを出たことを示し、falseはノーを意味します。この行は列の問題を解決するので、斜め方向の問題を解決するにはどうすればよいですか?質問で指定された斜め方向がすべてy = x + b / y = -x + b方程式に準拠していることを確認します。b = yx / b = x + y。同じbは同じスラッシュです。私のコードでは、d []は斜め方向を示し、ud []は逆の斜め方向を示します。たとえば、d [u + i]は、x = u、y = i、およびb = u + iの対角線上にピースがないことを意味します。前述のように、傾きは同じであるため、bが異なる限り、傾きは異なります。同様に、逆方向も同じで、b = yxを使用して判断しますが、yx <0の場合、+ nだけオフセットし、ud [i-u + n]を使用する必要があります。

  if(!row [i] &&!d [u + i] &&!ud [i-u + n])は、ポイントx = u、y = iについて、同じ列である限り、2つのスラッシュがないことを意味しますチェスの駒、要件を満たし、駒を置きます。

  残りはdfsの基本的な操作です、それを復元してください...

#include <iostream> 
#include <cstdio> 
#include <cstring>
 using  namespace std;
const  int N = 27 ;
char m [N] [N];
bool row [N]、d [N]、ud [N];
int n;
void first()
{ 
    forint i = 0 ; i <n; i ++ forint j = 0 ; j <n; j ++ 
            m [i] [j] = ' ' ; 
    memset(行、falsesizeof (行)); 
    memset(d、falsesizeof (d)); 
    memset(ud、falsesizeof (ud)); 
} 
void dfs(int u)
{ 
    // cout << u << endl; 
    if(u == n)
    { 
        forint i = 0 ; i <n; i ++ 
        { 

            forint j = 0 ; j <n; j ++ 
                cout << m [i] [j]; 
                cout << endl;
        }
        cout << endl;
        戻る; 
    } 
    forint i = 0 ; i <n; i ++ 
    { 
        if(!row [i] &&!d [u + i] &&!ud [i-u + n])
        { 
            m [u] [i] = ' Q ' ; 
            row [i] = d [u + i] = ud [i-u + n] = true ; 
            dfs(u + 1 ); 
            row [i] = d [u + i] = ud [i-u + n] = false ; 
            m [u] [i] = ' ' ; 
        }
    } 
} 
int main()
{ 

    while(cin >> n)
    { 
        first(); 
        dfs(0 ); 
    } 
}

もう1つのより基本的な検索方法は低速です。クイーン数を記録し、== nの場合に出力します。

#include <iostream> 
#include <cstdio> 
#include <cstring>
 using  namespace std;
const  int N = 27 ;
char m [N] [N];
bool row [N]、d [N]、ud [N]、urow [N];
int n;
void dfs(int x、int y、int s)
{ 
    // cout << x << "" << y << "" << s << endl; 
    if(y == n)
    { 
        x ++ ; 
        y = 0 ;
    
        if(s == n)  // この行をif(x == n)に入れることはできません。数がいくつになっても、
        {
             forint i = 0 ; i <n; i ++ 
            puts( m [i]); 
            puts("" ); 
        } 
        return ; 
    } 
    if(!row [x] &&!urow [y] &&!d [x + y] &&!ud [y-x + n])
    { 
        m [ x] [y] = ' Q ' ; 
        行[x] = urow [y] = d [x + y] = ud [y-x + n] = true ; 
        dfs(x、y + 1、s + 1) ;
        m [x] [y] = ' ' ; 
        row [x] = urow [y] = d [x + y] = ud [y-x + n] = false ; 
    } 
    dfs(x、y + 1 、s); 
} 
int main()
{ 
    // int n; 
    cin >> n;
    forint i = 0 ; i <n; i ++ forint j = 0 ; j <n; j ++ 
            m [i] [j] = ' ' ; 
    DFS(000); 
}

 

おすすめ

転載: www.cnblogs.com/liyexin/p/12680826.html