Now an emergent task for you is to open a password lock. The password
is consisted of four digits. Each digit is numbered from 1 to 9. Each
time, you can add or minus 1 to any digit. When add 1 to ‘9’, the
digit will change to be ‘1’ and when minus 1 to ‘1’, the digit will
change to be ‘9’. You can also exchange the digit with its neighbor.
Each action will take one step.Now your task is to use minimal steps to open the lock.
Note: The leftmost digit is not the neighbor of the rightmost digit.
Input
The input file begins with an integer T, indicating the number of test
cases.Each test case begins with a four digit N, indicating the initial
state of the password lock. Then followed a line with anotther four
dight M, indicating the password which can open the lock. There is one
blank line after each test case.Output
For each test case, print the minimal steps in one line.
Sample Input
2 1234 2144 1111 9999
Sample Output
2 4
题目大意:就是一个密码锁,给定一个初始状态,一个终点状态,求最小的步数,而且1可以转到2和9,9也可以转到1和8,其他的数字只能转到相邻的数,而且,可以交换相邻的两个数,也算作一步
思路:可以发现密码锁只有4为,所以存在的状态数并不多999*9个状态,从当前状态转移到下一个状态有8+3=11种,
8是每个数字+或者-,3 是相邻的两个数字交换。而且要求最短路径,所以用bfs解决
总结:
代码比较长,应该可以写的更加简便;bfs写的还不够熟练,关键点是状态的转移,以及标记数组,这个题可以很好的练练手
#include <bits/stdc++.h>
using namespace std;
const int maxn=9*9*9*9+10;
int vis[10][10][10][10];
int a,b,c,d,e1,e2,e3,e4;
string s1,s2;
int dir[8][4]={
1,0,0,0,
0,1,0,0,
0,0,1,0,
0,0,0,1,
-1,0,0,0,
0,-1,0,0,
0,0,-1,0,
0,0,0,-1
};
typedef struct node
{
int lock[4];
int step;
node()
{
step=0;
for(int i=0;i<4;i++)
lock[i]=maxn;
}
}node;
int bfs()
{
int ans=maxn;
queue<node> Q;
node point;
point.lock[0]=a;
point.lock[1]=b;
point.lock[2]=c;
point.lock[3]=d;
point.step=0;
vis[a][b][c][d]=0;
Q.push(point);
while(!Q.empty())
{
point=Q.front();
Q.pop();
node new_node;
//in the end
if(point.lock[0]==e1 && point.lock[1]==e2 && point.lock[2]==e3 && point.lock[3]==e4)
{
ans=min(ans,point.step);
continue;
}
//3dir
if(vis[point.lock[1]][point.lock[0]][point.lock[2]][point.lock[3]] > point.step+1)
{
int t=point.lock[0];
new_node.lock[0]=point.lock[1];
new_node.lock[1]=t;
new_node.lock[2]=point.lock[2];
new_node.lock[3]=point.lock[3];
new_node.step=point.step+1;
vis[point.lock[1]][point.lock[0]][point.lock[2]][point.lock[3]] = point.step+1;
Q.push(new_node);
// printf("new= %d %d %d %d\n",new_node.lock[0],new_node.lock[1],new_node.lock[2],new_node.lock[3]);
}
if(vis[point.lock[0]][point.lock[2]][point.lock[1]][point.lock[3]] > point.step+1)
{
int t=point.lock[1];
new_node.lock[0]=point.lock[0];
new_node.lock[1]=point.lock[2];
new_node.lock[2]=t;
new_node.lock[3]=point.lock[3];
new_node.step=point.step+1;
vis[point.lock[0]][point.lock[2]][point.lock[1]][point.lock[3]] = point.step+1;
Q.push(new_node);
// printf("new= %d %d %d %d\n",new_node.lock[0],new_node.lock[1],new_node.lock[2],new_node.lock[3]);
}
if(vis[point.lock[0]][point.lock[1]][point.lock[3]][point.lock[2]] > point.step+1)
{
int t=point.lock[2];
new_node.lock[0]=point.lock[0];
new_node.lock[1]=point.lock[1];
new_node.lock[2]=point.lock[3];
new_node.lock[3]=t;
new_node.step=point.step+1;
vis[point.lock[0]][point.lock[1]][point.lock[3]][point.lock[2]] = point.step+1;
Q.push(new_node);
// printf("new= %d %d %d %d\n",new_node.lock[0],new_node.lock[1],new_node.lock[2],new_node.lock[3]);
}
//8 dir
for(int i=0;i<8;i++)
{
new_node.lock[0]=(point.lock[0]+dir[i][0]);
new_node.lock[1]=(point.lock[1]+dir[i][1]);
new_node.lock[2]=(point.lock[2]+dir[i][2]);
new_node.lock[3]=(point.lock[3]+dir[i][3]);
for(int j=0;j<4;j++){
if(new_node.lock[j]==0)new_node.lock[j]=9;
if(new_node.lock[j]==10)new_node.lock[j]=1;
}
// printf("new= %d %d %d %d\n",new_node.lock[0],new_node.lock[1],new_node.lock[2],new_node.lock[3]);
if(vis[new_node.lock[0]][new_node.lock[1]][new_node.lock[2]][new_node.lock[3]] >point.step+1)
{
vis[new_node.lock[0]][new_node.lock[1]][new_node.lock[2]][new_node.lock[3]]=point.step+1;
new_node.step=point.step+1;
Q.push(new_node);
}
}
}
return ans;
}
int main()
{
int t;
cin>>t;
while(t--)
{
cin>>s1>>s2;
a=s1[0]-'0';b=s1[1]-'0';c=s1[2]-'0';d=s1[3]-'0';
e1=s2[0]-'0';e2=s2[1]-'0';e3=s2[2]-'0';e4=s2[3]-'0';
for(int i=0;i<10;i++)
for(int j=0;j<10;j++)
for(int k=0;k<10;k++)
for(int u=0;u<10;u++)
vis[i][j][k][u]=maxn;
int ans=bfs();
cout<<ans<<endl;
}
return 0;
}
/*
10
1234
2143
*/