Open the Lock(难度:1)
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 65536/32768 K (Java/Others)
Problem Description
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
思路:
题意:给出两个4位数,分别代表起始数字和目标密码,对起始数字的每一位进行加1、减1、交换位置操作,问经过多少步后可以达到目标密码。
注意:9加1后变成1,1减1后变成9,将输入的数字当做字符串处理,vis数组是四维数组。
方法:广度优先搜索。
AC代码:
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
struct node{
int num[4];//密码锁的四位状态
int step;//当前步数
};
char str[2][5];//数字当作字符串输入
int vis[10][10][10][10];
int pwd[4];//正确密码
//广搜
int bfs()
{
node cur,nex;//目前节点,下一个扩展节点
for(int i=0;i<4;i++)
{
cur.num[i]=str[0][i]-'0';
pwd[i]=str[1][i]-'0';//把字符串映射为数字
}
memset(vis,0,sizeof(vis));
cur.step=0;
queue<node>q;
q.push(cur);
int lock;//判断是否为正确密码
while(!q.empty())//当前队列仍有元素可扩展
{
cur=q.front();//得到队头状态
q.pop();//从队列中弹出队头状态
lock=1;//初始化为1
for(int i=0;i<4;i++)//与密码不同lock=0
{
if(cur.num[i]!=pwd[i])
{
lock=0;
break;
}
}
if(lock)//lock=1代表与密码相同
{
return cur.step;
}
for(int i=0;i<4;i++)//+
{
nex=cur;
if(cur.num[i]==9) nex.num[i]=1;//9加1为1
else nex.num[i]=cur.num[i]+1;//其他正常加1
if(!vis[nex.num[0]][nex.num[1]][nex.num[2]][nex.num[3]])
{
vis[nex.num[0]][nex.num[1]][nex.num[2]][nex.num[3]]=1;
nex.step=cur.step+1;
q.push(nex);
}
}
for(int i=0;i<4;i++)//-
{
nex=cur;
if(cur.num[i]==1) nex.num[i]=9;//1减1为9
else nex.num[i]=cur.num[i]-1;//其他正常减1
if(!vis[nex.num[0]][nex.num[1]][nex.num[2]][nex.num[3]])
{
vis[nex.num[0]][nex.num[1]][nex.num[2]][nex.num[3]]=1;
nex.step=cur.step+1;
q.push(nex);
}
}
for(int i=0;i<3;i++)//交换
{
nex=cur;
nex.num[i]=cur.num[i+1];
nex.num[i+1]=cur.num[i];
if(!vis[nex.num[0]][nex.num[1]][nex.num[2]][nex.num[3]])
{
vis[nex.num[0]][nex.num[1]][nex.num[2]][nex.num[3]]=1;
nex.step=cur.step+1;
q.push(nex);
}
}
}
}
int main()
{
int t;
cin>>t;
while(t--)
{
cin>>str[0]>>str[1];
cout<<bfs()<<endl;
}
return 0;
}