题目

July 6, 2021 · View on GitHub

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

参考答案

#include<cstdio>
#include<cmath>
#include<cstring> 
#include<queue> 
#include<algorithm>
#include<iostream>
#define N 10000
using namespace std;
int sign[10][6]=
{
    1,0,0,0,0,0,
    1,1,0,0,0,0,
    1,1,1,0,0,0,
    1,1,1,1,0,0,
    1,1,1,1,1,0,
    1,1,1,1,1,1,
    1,0,0,0,0,1,
    1,1,0,0,0,1,
    1,1,1,0,0,1,
    1,1,1,1,0,1
};
struct data
{
       int num[6],st,sta,pos;
};
int vi[6][6][6][6][6][6][6][10];
int com[N][8];
char si[7],di[7];
int a[6],b[6];
int cnt;
int check(data & t)
{
    return vi[t.num[0]][t.num[1]][t.num[2]][t.num[3]][t.num[4]][t.num[5]][t.pos][t.sta];
}
void gao(data & t)
{
    vi[t.num[0]][t.num[1]][t.num[2]][t.num[3]][t.num[4]][t.num[5]][t.pos][t.sta]=1;
} 
void bfs()
{
     cnt=0;
    // memset(vi,0,sizeof(vi));
     queue<data>q;
     data s,t;
     for(int i=0;i<6;i++)
     s.num[i]=i;
     s.st=s.sta=s.pos=0;
     q.push(s);
     vi[0][1][2][3][4][5][0][0]=1;               
     while(!q.empty())
     {
                      s=q.front();
                      q.pop();
                      for(int i=0;i<6;i++)
                      com[cnt][i]=s.num[i];
                      com[cnt][6]=s.sta;
                      com[cnt++][7]=s.st;
                      t=s;
                      t.st++;
                      if(t.pos>0)
                      {
                                 swap(t.num[0],t.num[t.pos]);
                                 if(!check(t))
                                 {
                                              gao(t);
                                              q.push(t);
                                 }
                                 swap(t.num[0],t.num[t.pos]);
                      }
                      if(t.pos<5)
                      {
                                 int tmp=t.sta;
                                 t.pos++;
                                 if(t.pos>t.sta||(t.sta>5&&t.pos>t.sta-6)) 
                                 {
                                                                         if(t.sta==9)
                                                                         t.sta=5;
                                                                         else
                                                                         t.sta++; 
                                 }
                                 if(!check(t)) 
                                 {
                                               gao(t);
                                               q.push(t); 
                                 }
                                 t.sta=tmp;
                                 t.pos--;
                                 swap(t.num[5],t.num[t.pos]);
                                 if(t.sta<5)
                                 {
                                 t.sta+=6;
                                 if(t.sta>9)
                                 t.sta=5; 
                                 } 
                                 if(!check(t))
                                  {
                                               gao(t);
                                               q.push(t);
                                  }
                      } 
     }
}
int main()
{
    bfs();
    while(~scanf("%s%s",si,di))
    {
                               for(int i=0;i<6;i++)
                               {
                                       a[i]=si[i]-'0';
                                       b[i]=di[i]-'0';
                               }
                               int ans=9999999;
                               for(int i=0;i<cnt;i++)
                               {
                                       int st=com[i][7],j;
                                       for(j=0;j<6;j++)
                                       {
                                               if(a[com[i][j]]!=b[j]&&sign[com[i][6]][j]==0)
                                               break;
                                               st+=abs(a[com[i][j]]-b[j]); 
                                       }
                                       if(j==6&&st<ans)
                                                       ans=st;
                               } 
                               printf("%d\n",ans);
    }
    return 0;
}