リソース制限
時間制限:1.0sメモリ制限:512.0MB
問題の説明
n * nボードを指定した場合、ボード上にクイーンが使用できない場所がいくつかあります。ここで、チェス盤にn個の黒の女王とn個の白い女王を配置する必要があります。これにより、2つの黒の女王が同じ行、同じ列、または同じ対角線にならず、2つの白の女王が同じ行にありません同じ列または同じ対角線上。合計何種類のリリース方法を尋ねますか?nは8以下です。
入力フォーマット入力
の最初の行は整数nで、チェス盤のサイズを示します。
次のn行では、各行に0または1のn個の整数があります。整数が1の場合、対応する位置をクイーンとして配置できることを示します。整数が0の場合、対応する位置をクイーンとして配置できないことを示します。
出力フォーマット
は整数を出力し、合計で何種類のputメソッドを示すかを示します。
サンプル入力
4
1 1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1
サンプル出力
2
サンプル入力
4
1 0 1 1
1 1 1 1
1 1 1 1
1 1 1 1
サンプル出力
0
問題解決のアイデア:
正直なところ、この問題を最初に目にしたとき、私は戸惑いました。まず、チェスについて何も知りませんでした(後で、これに何か関係があることを知りませんでした)。 * nのすべての行列が、異なる対角線上ではなく、異なる行、異なる列を満たすことができるので、私は恥(恥を知らない)でBaiduプログラミングに直面し始め、兄の説明から、突然始めて後悔しました┭ ┮﹏┭┮。
真実に戻り、彼は自分の考えを説明し始めました。コード部は、判定機能部(白黒を含む)、配置機能部(白黒を含む)、メイン機能に分かれています。プロセスは次のとおりです。最初に黒のピースを配置し、depth-firstとforループを使用します。条件付きの判断を行うたびに、ほぼすべてのボードが一度訪問されます。判断が成功した場合、再帰的に呼び出しを続行できます。それ以外の場合、この方法はggで機能しません。その後、黒のチェスの駒のレイアウトが完了し、白のチェスの駒が配置されます。原理は黒のチェスの駒と同じです。最後に成功数を出力します。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 10;
int n;
int map_Q[maxn][maxn];
int posb[maxn]={0}; //黑皇后
int posw[maxn]={0}; //白皇后
int ans;
bool checkw( int cur) //检查函数
{
for( int i = 1; i < cur; i++)
if( posw[i] == posw[cur] || abs(i-cur) == abs(posw[i]-posw[cur])) //如果列相等或者在斜对角线上
return false;
return true;
}
bool checkb( int cur) //检查函数
{
for( int i = 1; i < cur; i++)
if( posb[i] == posb[cur] || abs(i-cur) == abs(posb[i]-posb[cur])) //如果列相等或者在斜对角线上
return false;
return true;
}
void dfs_white( int cur) //深度优先算法
{
if( cur == n+1) //白皇后也全部放完,次数+1
{
ans++;
}
for( int i = 1; i <= n; i++)
{
if( posb[cur] == i) //表示第cur列的第i行位置已经被黑皇后占用,
continue; //结束当前循环,i+1
if( map_Q[cur][i] == 0) //再判断前提条件是否成立
continue;
posw[cur] = i; //尝试把第cur列的白皇后放在第i行上
if( checkw(cur)) //判断能否放置白皇后
dfs_white(cur+1); //递归
}
}
void dfs_black( int cur)
{
if( cur == n+1) //当黑皇后处理完时,再处理白皇后
{
dfs_white(1);
}
for( int i = 1; i <= n; i++)
{
if( map_Q[cur][i] == 0) //如果第cur列第i行满足放皇后的前提条件即 mp[cur][i] == 1
continue; //如果不满足,则结束当前循环,进行下一次循环即i+1。
posb[cur] = i; //就尝试把第cur列的黑皇后放在第i行上
if( checkb(cur)) //然后判断该尝试是否成立,如成立,则进行递归,如不成立,则尝试把当前列的黑皇后放在下一行(i+1行)上。
dfs_black(cur+1); //递归
}
}
int main()
{
cin >> n;
for( int i = 1; i <= n; i++) //定义棋盘
for( int j = 1; j <= n; j++)
cin >> map_Q[i][j];
ans = 0;
dfs_black(1); //先把黑皇后放在第一列
cout << ans << endl;
return 0;
}
説明するこの兄のおかげで、コードはこの兄のコードに似ており、理解を容易にするためにいくつかのコメントを追加し、彼のリンクをリンクしました:link。