目次
トピック: 94. 順列列挙の再帰的実装 - AcWing 問題バンク
前に書かれています:
ブルーブリッジカップから1ヶ月も経たないうちに、
川や湖の噂によると、
Blue Bridge Cup のお気に入りのテストは、深さ優先探索と動的計画法です。
そのため、蘭橋杯は包祖杯、DP杯とも呼ばれています。
それからもちろん、深さ優先検索、いわゆる dfs から始めて、ゲームの準備をしました。
トピック: 94. 順列列挙の再帰的実装 - AcWing 問題バンク
質問を読む:
入力形式:
整数 n。
出力フォーマット:
すべてのソリューションを昇順で出力します (1 行に 1 つずつ)。
まず、同じ行にある 2 つの隣接する数字は、スペースで区切られます。
次に、2 つの異なる行について、添字に対応する数字を 1 つずつ比較し、辞書式順序が小さい方を 1 位にランク付けします。
データ範囲:
1≦n≦9
入力サンプル:
3
出力例:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
問題解決のアイデア:
この質問は、深さ優先探索の古典的な質問です。
深さ優先探索を使うと、
最初に注意すべき点は、
私たちが書いた再帰構造は、すべてのケースをトラバースできます。
検索を初めて学ぶとき、再帰的な検索ツリーの観測を描画する必要があります。
再帰は非常に抽象的で、絵を描くことで問題を解決することができます。(上記の再帰的検索の基本的な考え方に慣れておくことは常に良いことです)
次に具体的な考え方です。
テーマに合わせて、小さいものから大きいものまで各プランをアウトプットし、
辞書編集的に小さい数字が最初に配置され、
以下を観察して、再帰的な検索ツリーを描画します。
ルートノード: (例として n=3 を取り上げます)
下を検索:
小さいものから大きいものまで:
探し続ける、
使用済みの番号は使用されなくなりました。
検索を続ける:
出力する必要があるのは、一番下の行です。
コードの実装は次のとおりです。
コード:
//养成好习惯,把常用头文件包了
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
//数组大小比题目要求大就行,这题n <= 9
const int N = 10;
int n;
int st[N];
//创建一个数组用来判断位置是否已经有数据了
bool used[N];
void dfs(int u)
{
//已经递归搜索到底了
if(u == n)
{
//打印数组中存放的值
for(int i = 0; i < n; i++)
{
printf("%d ", st[i]);
}
puts("");
return;
}
else
{
for(int i = 0; i < n; i++)
{
//如果used[i]等于true,证明该位置已经被占用,直接让i++继续循环
if(!used[i])
{
//表示该位置已经占用
used[i] = true;
//将要打印的值存进数组
st[u] = i + 1;
//递归往下搜索
dfs(u + 1);
//位置恢复原样(没有被占用了)
used[i] = false;
}
}
}
}
int main()
{
scanf("%d", &n);
dfs(0);
return 0;
}
交流 !!!!!!!!!!
最後に書く:
以上がこの記事の内容です、お読みいただきありがとうございます。
この記事が気に入ったら、いいねとコメントをお願いします。また、ご意見をお書きください。
私と一緒にプログラミングを学びたい場合は、私に従ってください。私たちは一緒に学び、成長します。
今後もより質の高いコンテンツを出力していきますので、よろしくお願いします。