Simple and easy to understand BFS (2) abstract BFS

I have reposted a BFS article before, but there are only some simple cases, and the original blogger did not add any remaining cases. It happened that I got a BFS question today, and I wrote it here as a supplement. This series will be updated if there is a chance.

Example: Open the Lock

There is a combination lock consisting of four digits, and each digit is one from 1 to 9.

For each operation: you can choose to add 1 or subtract 1 to the number in a position. You can also choose to swap the adjacent two digits. (Note: Add 1 to 9 to get 1, and to subtract 1 to get 9, and the first and fourth digits are not adjacent.)

Now for the initial state of the code lock and the final state of unlocking, it is required to output the minimum number of steps to open the code lock.

Input:
The first line of input is T, which indicates the number of test samples.

Each test sample has two lines. The first line is a four-digit N, which represents the initial state of the code lock, and the second line is a four-digit M, which represents the code to open the code lock.

There is a blank line in the input of each test sample.

Output:
For each test sample, output the minimum number of steps.

Sample Input:
2
1234
2144

1111
9999

Sample Output:
2
4

Idea: When you see the shortest steps required for the problem, you can know that it is solved with bfs. Use the vis four-dimensional array to mark whether a four-digit number has existed; in while, enumerate all operations separately

AC code:

#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;
}

Guess you like

Origin blog.csdn.net/weixin_45024585/article/details/107722398