J'ai republié un article de BFS auparavant, mais il n'y a que quelques cas simples, et le blogueur d'origine n'a pas complété les cas restants. Il se trouve que j'ai reçu une question BFS aujourd'hui, et je l'ai écrite ici en supplément. Cette série sera mise à jour s'il y a une chance.
Exemple: ouvrir la serrure
Il y a une serrure à combinaison composée de quatre chiffres, et chaque chiffre est un de 1 à 9.
Pour chaque opération: vous pouvez choisir d'ajouter 1 ou de soustraire 1 au nombre d'une position. Vous pouvez également choisir d'échanger les deux chiffres adjacents. (Remarque: ajoutez 1 à 9 pour obtenir 1 et soustrayez 1 pour obtenir 9, et les premier et quatrième chiffres ne sont pas adjacents.)
Maintenant, pour l'état initial du verrou à code et l'état final du déverrouillage, il est nécessaire de sortir le nombre minimum d'étapes pour ouvrir le verrou à code.
Entrée:
La première ligne d'entrée est T, qui indique le nombre d'échantillons de test.
Chaque échantillon de test comporte deux lignes. La première ligne est un N à quatre chiffres, qui représente l'état initial du verrou à code, et la deuxième ligne est un M à quatre chiffres, qui représente le code permettant d'ouvrir le verrou à code.
Il y a une ligne vide dans l'entrée de chaque échantillon de test.
Sortie:
pour chaque échantillon de test, indiquez le nombre minimum d'étapes.
Exemple d'entrée :
2
1234
2144
1111
9999
Exemple de sortie :
2
4
Idée: lorsque vous voyez les étapes les plus courtes requises pour le problème, vous pouvez savoir qu'il est résolu avec bfs. Utilisez le tableau à quatre dimensions vis pour indiquer si un certain nombre à quatre chiffres a existé; dans while, énumérez toutes les opérations séparément
Code 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;
}