阿兰是某机密部门的打字员,她现在接到一个任务:需要在一天之内输入几百个长度固定为6的密码。当然,她希望输入的过程中敲击键盘的总次数越少越好。 不幸的是,出于保密的需要,该部门用于输入密码的键盘是特殊设计的,键盘上没有数字键,而只有以下六个键:Swap0, Swap1, Up, Down, Left, Right,为了说明这6个键的作用,我们先定义录入区的6个位置的编号,从左至右依次为1,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
【题目来源】
NOI 2001
/* type by Spray_of_learn submit three times the first time runtime error the second time time time limited error the third time accept we can ignore the 'left' we can calculate the 'up' and 'down' in the end */ #include <cstdio> #include <cstring> #define INF_MAX 2147483647 #define MAXQ 1000000 int start,end; struct que{ int line,len,flag; int data[10]; }f[MAXQ]; bool hash[10][10][10][10][10][10][7]; void swap(int &a,int &b){int c=a;a=b;b=c;} /* int swap0(int x,int l){ int a[7]; int t=7; while (x){ a[--t]=x % 10; x/=10; } swap(a[1],a[l]); int sum=0; for (int i=1;i<=6;i++) sum=sum*10+a[i]; return sum; } int swap1(int x,int l){ int a[7]; int t=7; while (x){ a[--t]=x % 10; x/=10; } swap(a[6],a[l]); int sum=0; for (int i=1;i<=6;i++) sum=sum*10+a[i]; return sum; } int up(int x,int l){ int a[7]; int t=7; while (x){ a[--t]=x % 10; x/=10; } if (a[l]<9) a[l]++; int sum=0; for (int i=1;i<=6;i++) sum=sum*10+a[i]; return sum; } int down(int x,int l){ int a[7]; int t=7; while (x){ a[--t]=x % 10; x/=10; } if (a[l]>1) a[l]--; int sum=0; for (int i=1;i<=6;i++) sum=sum*10+a[i]; return sum; } */ int END[10]; int START[10]; void changeSTART(){ int t=7; int x=start; while (x){ START[--t]=x % 10; x /= 10; } } void changeEND(){ int t=7; int x=end; while (x){ END[--t]=x % 10; x /= 10; } } /* bool checkans(int *x,int len){ bool flag=false; for (int i=1;i<=6;i++){ if (END[i]!=x[i]){flag=true;break;} } if (!flag){ printf("%d\n",len+1); return true; } return false; } */ int ans=INF_MAX; void checkans(int *x,int head){ int tot=f[head].len; for (int i=1;i<=6;i++){ if ((i!=6 || !f[head].flag) && i>f[head].line && START[f[head].data[i]]!=END[i]) return; else tot+=((START[f[head].data[i]]-END[i])>0?(START[f[head].data[i]]-END[i]):(-START[f[head].data[i]]+END[i])); } if (ans>tot) ans=tot; } int main(){ freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); scanf("%d %d",&start,&end); changeEND(); changeSTART(); int head=0,tail=1; // memcpy(f[tail].data,START,sizeof(START)); for (int i=1;i<=6;i++) f[tail].data[i]=i; f[tail].line=1; /* hash[START[1]][START[2]][START[3]][START[4]][START[5]][START[6]][1]=true; if (start==end) { printf("0"); return 0; } */ hash[1][2][3][4][5][6][1]=true; checkans(START,0); while (head!=tail){ head++; if (head==MAXQ) head=1; int l=f[head].line; int x[10]; memcpy(x,f[head].data,sizeof(x)); //left /* if (l>1){ if (!hash[x[1]][x[2]][x[3]][x[4]][x[5]][x[6]][l-1]){ tail++; if (tail==MAXQ) tail=1; memcpy(f[tail].data,x,sizeof(x)); f[tail].line=l-1; f[tail].len=f[head].len+1; hash[x[1]][x[2]][x[3]][x[4]][x[5]][x[6]][l-1]=true; } } */ /* //up if (x[l]<9){ x[l]++; if (checkans(x,f[head].len)) break; if (!hash[x[1]][x[2]][x[3]][x[4]][x[5]][x[6]][l]){ tail++; if (tail==MAXQ) tail=1; memcpy(f[tail].data,x,sizeof(x)); f[tail].line=l; f[tail].len=f[head].len+1; hash[x[1]][x[2]][x[3]][x[4]][x[5]][x[6]][l]=true; } x[l]--; } //down if (x[l]>0){ x[l]--; if (checkans(x,f[head].len)) break; if (!hash[x[1]][x[2]][x[3]][x[4]][x[5]][x[6]][l]){ tail++; if (tail==MAXQ) tail=1; memcpy(f[tail].data,x,sizeof(x)); f[tail].line=l; f[tail].len=f[head].len+1; hash[x[1]][x[2]][x[3]][x[4]][x[5]][x[6]][l]=true; } x[l]++; } */ //swap0 if (l>1){ swap(x[1],x[l]); // if (checkans(x,f[head].len)) break; if (!hash[x[1]][x[2]][x[3]][x[4]][x[5]][x[6]][l]){ tail++; if (tail==MAXQ) tail=1; memcpy(f[tail].data,x,sizeof(x)); f[tail].line=l; f[tail].len=f[head].len+1; f[tail].flag=f[head].flag; hash[x[1]][x[2]][x[3]][x[4]][x[5]][x[6]][l]=true; checkans(x,tail); } swap(x[1],x[l]); } //swap1 if (l<6){ swap(x[6],x[l]); checkans(x,head); // if (checkans(x,f[head].len)) break; if (!hash[x[1]][x[2]][x[3]][x[4]][x[5]][x[6]][l]){ tail++; if (tail==MAXQ) tail=1; memcpy(f[tail].data,x,sizeof(x)); f[tail].line=l; f[tail].len=f[head].len+1; f[tail].flag=1; hash[x[1]][x[2]][x[3]][x[4]][x[5]][x[6]][l]=true; checkans(x,tail); } swap(x[6],x[l]); } //right if (l<6){ if (!hash[x[1]][x[2]][x[3]][x[4]][x[5]][x[6]][l+1]){ tail++; if (tail==MAXQ) tail=1; memcpy(f[tail].data,x,sizeof(x)); f[tail].line=l+1; f[tail].len=f[head].len+1; f[tail].flag=f[head].flag; hash[x[1]][x[2]][x[3]][x[4]][x[5]][x[6]][l+1]=true; checkans(x,tail); } } } printf("%d\n",ans); return 0; }