阿兰是某机密部门的打字员,她现在接到一个任务:需要在一天之内输入几百个长度固定为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; }