BFS simple y fácil de entender (2) resumen BFS

He vuelto a publicar un artículo de BFS antes, pero solo hay algunos casos simples, y el blogger original no complementó los casos restantes. Sucedió que hoy recibí una pregunta de BFS y la escribí aquí como un suplemento. Esta serie se actualizará si existe la posibilidad.

Ejemplo: abrir la cerradura

Hay un candado de combinación que consta de cuatro dígitos, y cada dígito es uno del 1 al 9.

Para cada operación: puede optar por sumar 1 o restar 1 al número en una posición. También puede optar por intercambiar los dos dígitos adyacentes. (Nota: sume 1 a 9 para obtener 1, y reste 1 para obtener 9, y el primer y cuarto dígitos no son adyacentes).

Ahora, para el estado inicial del código de bloqueo y el estado final de desbloqueo, se requiere generar el número mínimo de pasos para abrir el código de bloqueo.

Entrada:
La primera línea de entrada es T, que indica el número de muestras de prueba.

Cada muestra de prueba tiene dos líneas: la primera línea es una N de cuatro dígitos, que representa el estado inicial del código de bloqueo, y la segunda línea es una M de cuatro dígitos, que representa el código para abrir el código de bloqueo.

Hay una línea en blanco en la entrada de cada muestra de prueba.

Salida:
Para cada muestra de prueba, envíe el número mínimo de pasos.

Entrada de muestra:
2
1234
2144

1111
9999

Salida de muestra:
2
4

Idea: Cuando vea los pasos más cortos requeridos para el problema, puede saber que se resuelve con bfs. Use la matriz vis de cuatro dimensiones para marcar si ha existido un cierto número de cuatro dígitos; en while, enumere todas las operaciones por separado

Código 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;
}

Supongo que te gusta

Origin blog.csdn.net/weixin_45024585/article/details/107722398
Recomendado
Clasificación