Description
现在一个紧急的任务是打开一个密码锁。密码由四位数字组成,每个数字从 1 到 9 进行编号。每次可以对任何数字加 1 或减 1。当将9加 1 时,数字将变为1,当1减 1 的时,数字将变为9。您也可以与邻居交换数字,每一个行动记做一步。现在你的任务是使用最小的步骤来打开锁。
注意:最左边的数字不是最右边数字的邻居。
Input
第一行输入四位数字,表示密码锁的初始状态。第二行输入四位数字,表示开锁的密码。
Output
输出一个整数,表示最小步骤。
Sample Input 1
1234
2144
Sample Output 1
2
这道题一看,似乎不该用搜索。
又一想,这种题目也只能使用bfs来完成。
但是怎么打标记?
普通的一维的vis数组已经无法满足这道题目的需求了,应该怎么解决?
再认真一看,它的起始和重点都是4个数字构成,我们可以把由4个数字组成的一组密码记为一种状态,即:
当密码为abcd时,对应的标记就应该记为vis[a][b][c][d]=1;
简单来说,就是通过四维数组,完成打标记这一步。
接下来的操作就是最基本的bfs,代码随便敲下来就可以了。
按照题意,每个密码能够进行的拓展操作分别为:
每一位加/减一位构成的新密码;
分别交换第1,2/2,3/3,4位构成的新密码;
然后判断,如果是没有打标记的,打进队列然后打标记即可。
AC代码:
#include<bits/stdc++.h>
using namespace std;
struct node
{
int aa[4];
int t;
node(){};
node(int a0,int a1,int a2,int a3,int t_)
{
aa[0]=a0;
aa[1]=a1;
aa[2]=a2;
aa[3]=a3;
t=t_;
}
}mb;//mb:目标
bool x[10][10][10][10];
queue<node> qu;
bool in(node a)
{
if(a.aa[0]==mb.aa[0]&&a.aa[1]==mb.aa[1]&&a.aa[2]==mb.aa[2]&&a.aa[3]==mb.aa[3])return false;
else return true;
}
int bfs(int a,int b,int c,int d)
{
qu.push(node(a,b,c,d,0));
x[a][b][c][d]=1;
while(in(qu.front())&&!qu.empty())
{
node now=qu.front();
qu.pop();
if(!x[now.aa[1]][now.aa[0]][now.aa[2]][now.aa[3]])
{
qu.push(node(now.aa[1],now.aa[0],now.aa[2],now.aa[3],now.t+1));
x[now.aa[1]][now.aa[0]][now.aa[2]][now.aa[3]]=1;
}
//a,b,c,d->b,a,c,d
if(!x[now.aa[0]][now.aa[2]][now.aa[1]][now.aa[3]])
{
qu.push(node(now.aa[0],now.aa[2],now.aa[1],now.aa[3],now.t+1));
x[now.aa[0]][now.aa[2]][now.aa[1]][now.aa[3]]=1;
}
//a,b,c,d->a,c,b,d
if(!x[now.aa[0]][now.aa[1]][now.aa[3]][now.aa[2]])
{
qu.push(node(now.aa[0],now.aa[1],now.aa[3],now.aa[2],now.t+1));
x[now.aa[0]][now.aa[1]][now.aa[3]][now.aa[2]]=1;
}
//a,b,c,d->a,b,d,c
//因为a和d 不能直接交换所以就只有这三种情况
for(int i=0;i<4;i++)
{
node nxt=now;
nxt.aa[i]++;
nxt.t++;
if(nxt.aa[i]==10)nxt.aa[i]=1;
if(!x[nxt.aa[0]][nxt.aa[1]][nxt.aa[2]][nxt.aa[3]])
{
qu.push(nxt);
x[nxt.aa[0]][nxt.aa[1]][nxt.aa[2]][nxt.aa[3]]=1;
}
}
for(int i=0;i<4;i++)
{
node nxt=now;
nxt.aa[i]--;
nxt.t++;
if(nxt.aa[i]==0)nxt.aa[i]=9;
if(!x[nxt.aa[0]][nxt.aa[1]][nxt.aa[2]][nxt.aa[3]])
{
qu.push(nxt);
x[nxt.aa[0]][nxt.aa[1]][nxt.aa[2]][nxt.aa[3]]=1;
}
}
}
return qu.front().t;
}
int main()
{
int st,ed;
cin>>st>>ed;
mb=node(ed/1000,ed%1000/100,ed%100/10,ed%10,0);
cout<<bfs(st/1000,st%1000/100,st%100/10,st%10)<<endl;
return 0;
}
ov.