目次
トピック: 1114. チェス盤の問題 - AcWing 問題バンク
前に書かれています:
どうすればアルゴリズムをうまく学習できますか?
個人的には質問の体系的なブラッシングが特に重要だと思いますが、
そのため、深さ優先探索を上手に学ぶために、暴力的な探索を使ってブルーブリッジカップに対処するために、
さっそくクイズを始めましょう!
タイトル: 1114. チェス盤の問題 - AcWing Question Bank
タイトル説明:
入力形式:
入力には、複数のテスト データ セットが含まれています。
各データセットの最初の行は、スペースで区切られた 2 つの正の整数 n、k です。
チェス盤が n ∗ n の行列で記述され、配置された駒の数も示されることを示します。
-1 -1
は入力の終了を示します。
次の n 行は、チェッカーボードの形状を記述します。各行には n 文字があり、 #
チェッカーボード領域が表されます。
.
空白領域を示します (データに余分な空白行または空白列がないことが保証されます)。
出力フォーマット:
データのセットごとに、出力の行が与えられ、出力に配置されるスキームの数は C (データ保証 C < 231) です。
データ範囲:
n≦8、k≦n
入力サンプル:
2 1
#.
.#
4 4
...#
..#.
.#..
#...
-1 -1
出力例:
2
1
問題解決のアイデア:
深さ優先探索を使うと、
最初の注意点は、検索の順序です。
確認したいので、
すべてのケースをトラバースできる再帰構造を作成しました。
(上記の再帰的検索の基本的な考え方に慣れておくことは常に良いことです)
次は具体的なアイデア です:
質問の意味によると、次の 2 つの質問を要約できます。
1. チェスは「.」の位置ではなく、「#」の位置でのみプレイできます。
2. 各行と各列には 1 つのチェスしか許可されていません。
最初の質問では、判断を追加できます。
2 番目の質問は、シミュレートする必要があります: (3 行 3 列のチェス盤を例にとります)
再帰探索木を描く:
各水平線が行であると仮定し、毎回次の列を再帰的に検索します。
ルート ノード:
次に、最初の行を列 1、2、および 3 に配置できます。
それに応じて再帰的に検索します。
逃した列は、再帰を続けた後に配置できません。
再帰的に検索を続けます:
これは実際には完全順列であり、完全順列のアイデアに従って実行できることがわかりました。
コードの実装は次のとおりです。
コード:
//包常用头文件
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int n, k;
const int N = 10;
//计数
int res;
char g[N][N];
//记录这一列有没有下棋
bool used[N];
void dfs(int u, int cnt)
{
//下的棋数符合题目要求,方案++
if(cnt == k)
{
res++;
return;
}
//已经到行底了
if(u == n) return;
for(int i = 0; i < n; i++)
{
if(!used[i] && g[u][i] == '#')
{
used[i] = true;
dfs(u + 1, cnt + 1);
used[i] = false;//恢复现场
}
}
//如果前面(下的棋数符合题目要求,方案++),就会返回,导致到不了下一行,这里让他强行往下走一行
dfs(u + 1, cnt);
}
int main()
{
//多组输入
while(cin >> n >> k && n > 0 && k > 0)
{
for(int i = 0; i < n; i++)
{
cin >> g[i];
}
//每组输入重新计数
res = 0;
dfs(0, 0);
printf("%d\n", res);
}
return 0;
}
交流 !!!!!!!!!!
最後に書く:
以上がこの記事の内容です、お読みいただきありがとうございます。
この記事が気に入ったら、いいねとコメントをお願いします。また、ご意見をお書きください。
私と一緒にプログラミングを学びたい場合は、私に従ってください。私たちは一緒に学び、成長します。
今後もより質の高いコンテンツを出力していきますので、よろしくお願いします。