现在一个紧急的任务是打开一个密码锁。密码由四位数字组成,每个数字从 1 到 9 进行编号。每次可以对任何一位数字加 1 或减 1。当将9
加 1 时,数字将变为1
,当1
减 1 时,数字将变为9
。你也可以交换相邻数字,每一个行动记做一步。现在你的任务是使用最小的步骤来打开锁。注意:最左边的数字不与最右边的数字相邻。
输入格式
第一行输入四位数字,表示密码锁的初始状态。
第二行输入四位数字,表示开锁的密码。
输出格式
输出一个整数,表示最小步骤。
样例输入复制
1234 2144
样例输出复制
2
思路:
看见题目要求最短步骤就可以知道用bfs来解决了,用vis四维数组来标记某个四位数是否存在过;
在while里面,分别枚举所有的操作
代码:
#include<bits/stdc++.h>
#include<queue>
using namespace std;
struct node{
int a[4];
int step;
}first, target;
int vis[11][11][11][11]; //标记某个四位数是否出现
void bfs(){
node s, next;
queue<node> q;
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(){
char s1[4], s2[4];
scanf("%s%s", s1, s2);
for(int i = 0; i < 4; i++){ //把初始值和目标值分别赋给它们
first.a[i] = s1[i] - '0';
target.a[i] = s2[i] - '0';
}
bfs();
return 0;
}