阿兰是某机密部门的打字员,她现在接到一个任务:需要在一天之内输入几百个长度固定为6的密码。当然,她希望输入的过程中敲击键盘的总次数越少越好。
不幸的是,出于保密的需要,该部门用于输入密码的键盘是特殊设计的,键盘上没有数字键,而只有以下六个键:Swap0,Swap1,Up,Down,Left,Right。为了说明这6个键的
用,我们先定义录入区的6个位置的编号,从左至右依次为l,2,3,4,5,6。下面列出每个键的作用:
Swap0:按Swap0,光标位置不变,将光标所在位置的数字与录入区的1号位置的数字(左起第一个数字)交换。如果光标已经处在录入区的1号位置,则按Swap0键之后,录入区的数字不变;
Swap1:按Swap1,光标位置不变,将光标所在位置的数字与录入区的6号位置的数字(左起第六个数字)交换。如果光标已经处在录入区的6号位置,则按Swap1键之后,录入区的数字不变;
Up:按up,光标位置不变,将光标所在位置的数字加1(除非该数字是9)。例如,如果 光标所在位置的数字为2,按up之后,该处的数字变为3;如果该处数字为9,则按up之后,数字不变,光标位置也不变;
Down:按Down,光标位置不变,将光标所在位置的数字减1(除非该数字是0)。如果该 处数字为0,则按Down之后,数字不变,光标位置也不变;
Left:按Left,光标左移一个位置,如果光标已经在录入区的1号位置(左起第一个位 置)上,则光标不动;
Right:按Right,光标右移一个位置,如果光标已经在录入区的6号位置(左起第六个 位置)上,则光标不动。当然,为了使这样的键盘发挥作用,每次录入密码之前,录入区总会随机出现一个长度为6的初始密码,而且光标固定出现在1号位置上。当巧妙地使用上述六个特殊键之后,可以得到目标密码,这时光标允许停在任何一个位置。
现在,阿兰需要你的帮助,编写一个程序,求出录入一个密码需要的最少的击键次数。
【输入格式】
仅一行,含有两个长度为6的数,前者为初始密码,后者为目标密码,两个密码之间用 一个空格隔开。
【输出格式】
仅一行,含有一个正整数,为最少需要能击键次数。
【样例输入】
123456 654321
【样例输出】
11
题意是给定两个长度为6的串,要求用最小的步数从1串变成2串
ps:火男学长太神了,看一眼题目不屑的说,隐式图搜索。
唉真的是搜索,让我调了1个多小时
首先肯定用双向广搜啦
状态有600w。因为是6个光标的位置 * 100w的数据的状态
具体实现最好直接用数字保存状态,否则像hzwer那样字符串乱搞就T了,不要学他
另外,我写的很丑,勿喷
#include<cstdio>
const int mul[8]={0,1,10,100,1000,10000,100000,1000000};
int q[7000010];
int step[7000010];
int mark[7000010];
int a,b,t=0,w=7,now,opr,mov,side;
inline int abs(int x)
{if(x<0)x=-x;return x;}
int main()
{
freopen("typer.in","r",stdin);
freopen("typer.out","w",stdout);
scanf("%d%d",&a,&b);
q[1]=6*mul[7]+a;
mark[q[1]]=1;
for (int i=2;i<=7;i++)
{
q[i]=b+(i-1)*mul[7];
if (mark[q[i]])
{
printf("0");
return 0;
}
mark[q[i]]=-i;
}
while (t<w)
{
now=q[++t];
mov=step[t];
opr=now/mul[7];
side=0;
if (mark[now]<0) side=-1;
if (mark[now]>0) side=1;
if ((now/mul[opr])%10) //down
{
if (side*mark[now-mul[opr]]<0)
{
printf("%d",mov+1+step[abs(mark[now-mul[opr]])]);
return 0;
}
if (!mark[now-mul[opr]])
{
q[++w]=now-mul[opr];
step[w]=mov+1;
mark[q[w]]=w*side;
}
}
if ((now/mul[opr])%10!=9) //up
{
if (side*mark[now+mul[opr]]<0)
{
printf("%d",mov+1+step[abs(mark[now+mul[opr]])]);
return 0;
}
if (!mark[now+mul[opr]])
{
q[++w]=now+mul[opr];
step[w]=mov+1;
mark[q[w]]=w*side;
}
}
if (opr!=1) //swap1
{
int s=(now/mul[opr])%10,t=now%10;
if (side*mark[now+(t-s)*mul[opr]+(s-t)]<0)
{
printf("%d",mov+1+step[abs(mark[now+(t-s)*mul[opr]+(s-t)])]);
return 0;
}
if (!mark[now+(t-s)*mul[opr]+(s-t)])
{
q[++w]=now+(t-s)*mul[opr]+(s-t);
step[w]=mov+1;
mark[q[w]]=w*side;
}
}
if (opr!=6) //swap0
{
int s=(now/mul[opr])%10,t=(now/mul[6])%10;
if (side*mark[now+(t-s)*mul[opr]+(s-t)*mul[6]]<0)
{
printf("%d",mov+1+step[abs(mark[now+(t-s)*mul[opr]+(s-t)*mul[6]])]);
return 0;
}
if (!mark[now+(t-s)*mul[opr]+(s-t)*mul[6]])
{
q[++w]=now+(t-s)*mul[opr]+(s-t)*mul[6];
step[w]=mov+1;
mark[q[w]]=w*side;
}
}
if (opr!=1) //left
{
if (side*mark[now-mul[7]]<0)
{
printf("%d",mov+1+step[abs(mark[now-mul[7]])]);
return 0;
}
if (!mark[now-mul[7]])
{
q[++w]=now-mul[7];
step[w]=mov+1;
mark[q[w]]=w*side;
}
}
if (opr!=6) //right
{
if (side*mark[now+mul[7]]<0)
{
printf("%d",mov+1+step[abs(mark[now+mul[7]])]);
return 0;
}
if (!mark[now+mul[7]])
{
q[++w]=now+mul[7];
step[w]=mov+1;
mark[q[w]]=w*side;
}
}
}
return 0;
}