以前にBFSの記事を再投稿しましたが、単純なケースはいくつかあり、元のブロガーは残りのケースを補足していませんでした。今日、たまたまBFSの質問があり、補足としてここに書きました。このシリーズは、機会があれば更新されます。
例:ロックを開く
4桁のダイヤル錠があり、各桁は1から9までの1桁です。
操作ごとに:位置の数値に1を加算するか1を減算するかを選択できます。隣接する2桁を入れ替えることもできます。(注:1を9に加算して1を取得し、1を減算して9を取得し、1桁目と4桁目は隣接していません。)
ここで、コードロックの初期状態とロック解除の最終状態については、コードロックを開くための最小ステップ数を出力する必要があります。
入力:入力
の最初の行はTで、これはテストサンプルの数を示します。
各テストサンプルには2行あります。1行目はコードロックの初期状態を表す4桁のNで、2行目はコードロックを開くためのコードを表す4桁のMです。
各テストサンプルの入力には空白行があります。
出力:
各テストサンプルについて、最小ステップ数を出力します。
サンプル入力:
2
1234
2144
1111
9999
サンプル出力:
2
4
アイデア:問題に必要な最短の手順を見ると、bfsで解決されていることがわかります。vis4次元配列を使用して、特定の4桁の数字が存在するかどうかをマークします。その間、すべての操作を個別に列挙します。
ACコード:
#include<iostream>
#include <cstring>
#include<queue>
using namespace std;
struct node{
int a[4];
int step; //步数
}first,target;
char s1[4],s2[4];
int vis[11][11][11][11]; //标记某个四位数是否出现
void bfs(){
node s, next;
queue<node> q;
memset(vis,0, sizeof(vis));
s = first;
s.step = 0; //步数置为0
q.push(s);
vis[s.a[0]][s.a[1]][s.a[2]][s.a[3]] = true;
while(!q.empty()){
node t = q.front(); //队首元素放在t中
q.pop();
//如果找到目标,输出
if(t.a[0] == target.a[0] && t.a[1] == target.a[1] && t.a[2] == target.a[2] && t.a[3] == target.a[3]){
printf("%d\n", t.step);
return;
}
for(int i = 0; i < 4; i++){
//枚举四位数,都进行加一操作
next = t; //将t的值赋给next
next.a[i]++;
if(next.a[i] == 10)
next.a[i] = 1;
if(!vis[next.a[0]][next.a[1]][next.a[2]][next.a[3]]){
vis[next.a[0]][next.a[1]][next.a[2]][next.a[3]] = true;
next.step++;
q.push(next);
}
}
for(int i = 0; i < 4; i++){
next = t;
next.a[i]--;
if(next.a[i] == 0)
next.a[i] = 9;
if(!vis[next.a[0]][next.a[1]][next.a[2]][next.a[3]]){
vis[next.a[0]][next.a[1]][next.a[2]][next.a[3]] = true;
next.step++;
q.push(next);
}
}
for(int i = 0; i < 3; i++){
//从左到右交换相邻两个数
next = t;
next.a[i] = t.a[i + 1];
next.a[i + 1] = t.a[i];
if(!vis[next.a[0]][next.a[1]][next.a[2]][next.a[3]]){
vis[next.a[0]][next.a[1]][next.a[2]][next.a[3]] = true;
next.step++;
q.push(next);
}
}
}
}
int main(){
int testNum;
scanf("%d",&testNum);
while (testNum--) {
scanf("%s",s1);
scanf("%s",s2);
for(int i = 0; i < 4; i++){
//把初始值和目标值分别赋给它们
first.a[i] = s1[i] - '0';
target.a[i] = s2[i] - '0';
}
bfs();
if (testNum != 0) getchar();
}
return 0;
}