zoukankan      html  css  js  c++  java
  • CDQZ_Training 20120524 聪明的打字员

    题目:

    http://cdqz.openjudge.cn/noip/1012/

    时间限制:
    20000ms
    内存限制:
    128000kB
    描述

    阿兰是某机密部门的打字员,她现在接到一个任务:需要在一天之内输入几百个长度同定为6的密码。当然,她希望输入的过程中敲击键盘的总次数越少越好..

        不幸的是,出于保密的需要,该部门用于输入密码的键盘是特殊设计的,键盘上没有数字键,而只有以下六个键:Swap0.Swapl,up,down,Left,Right。为了说明这6个键的作用,我们先定义录入区的6个位置的编号,从左至右依次为l,2,3,4,5,6。下面列出每个键的作用:

      Swap0:按Swap0,光标位置不变,将光标所在位置的数字与录入区的l号位置的数字(左起第一个数字)交换。如果光标已经处在录入区的l号位置,则按Swap0键之后.录入区的数字不变;

      Swapl:按Swapl,光标位置不变,将光标所在位置的数字与录人区的6号位置的数字(左起第六个数字)交换。如果光标已经处在录人区的6号位置,则按Swapl键之后.录人区的数字不变;

      Up:按up,光标位置不变,将光标所在位置的数字加1(除非该数字是9)。例如,如果光标所在位置的数字为2,按up之后,该处的数字变为3;如果该处数字为9,则按up之后,数字不变,光标位置也不变;

        down:按Down,光标位置不变,将光标所在位置的数宁减1(除非该数字是0)。如果该处数字为0,则按Down之后,数字不变,光标位置也不变;

        Left:按Len,光标左移一个位置,如果光标已经在录入区的l号位置(左起笫一个位置)上,则光标不动;

        Right:按Right,光标右移一个位置,如果光标已经在录入医的6号位置(左起第六个位置)上,则光标不动。当然,为了使这样的键盘发挥作用,每次录入密码之前,录入区总会随机出现一个长度为6的初始密码.而且光标固定出现在1号位置上。当巧妙地使用上述六个特殊键之后,可以得到目标密码,这时光标允许停在任何一个位置。

        现在,阿兰需要你的帮助,编写一个程序,求出录人一个密码需要的最少的击键次数。

     

    输入
    仪一行,含有两个长度为6的数,前者为初始密码,后者为目标密码,两个密码之间用一个空格隔开。
    输出
    仅一行,含有一个正整数,为最少需要的击键次数。
    样例输入
    123456 654321
    样例输出
    11
     
    题解:
      赤裸裸的bfs…………………………但需要一定的优化:1、改变每次进行扩展时的操作顺序。2、加判重。3、双向bfs。
     
      我只用了第二种优化………………好像比较慢………………不过勉强可以过了………………
     
    View Code
      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<queue>
      5 
      6 using namespace std;
      7 
      8 int shi[10],s,e;
      9 
     10 bool ma[100000001];
     11 
     12 struct state
     13 {
     14        int v,step;
     15        state()
     16        {
     17                v=step=0;
     18        }
     19        state(int a,int b)
     20        {
     21                  v=a;step=b;
     22        } 
     23 };
     24 
     25 queue<state> que;
     26 
     27 bool work1(int v,int p,int s)
     28 {
     29      if (p==6) return false;
     30      int newv=v;
     31      newv=newv-v / shi[6] * shi[6];
     32      newv=newv-v / shi[p] % 10 * shi[p];
     33      newv=newv+v / shi[p] % 10 * shi[6];
     34      newv=newv+v / shi[6] * shi[p];
     35      if (newv==e)
     36      {
     37                  printf("%d\n",s+1);
     38                  return true;
     39      }
     40      if (!ma[newv*10+p])
     41      {
     42                         ma[newv*10+p]=true;
     43                         que.push(state(newv*10+p,s+1));
     44      }
     45      return false;
     46 }
     47 
     48 bool work2(int v,int p,int s)
     49 {
     50      if (p==1) return false;
     51      int newv=v;
     52      newv=newv-v % 10;
     53      newv=newv-v / shi[p] % 10 * shi[p];
     54      newv=newv+v / shi[p] % 10;
     55      newv=newv+v % 10 * shi[p];
     56      if (newv==e)
     57      {
     58                  printf("%d\n",s+1);
     59                  return true;
     60      }
     61      if (!ma[newv*10+p])
     62      {
     63                         ma[newv*10+p]=true;
     64                         que.push(state(newv*10+p,s+1));
     65      }
     66      return false;
     67 }
     68 
     69 bool work3(int v,int p,int s)
     70 {
     71      if (v / shi[p] % 10==9) return false;
     72      int newv=v+shi[p];
     73      if (newv==e)
     74      {
     75                  printf("%d\n",s+1);
     76                  return true;
     77      }
     78      if (!ma[newv*10+p])
     79      {
     80                         ma[newv*10+p]=true;
     81                         que.push(state(newv*10+p,s+1));
     82      }
     83      return false;
     84 }
     85 
     86 bool work4(int v,int p,int s)
     87 {
     88      if (v / shi[p] % 10==0) return false;
     89      int newv=v-shi[p];
     90      if (newv==e)
     91      {
     92                  printf("%d\n",s+1);
     93                  return true;
     94      }
     95      if (!ma[newv*10+p])
     96      {
     97                         ma[newv*10+p]=true;
     98                         que.push(state(newv*10+p,s+1));
     99      }
    100      return false;
    101 }
    102 
    103 bool work5(int v,int p,int s)
    104 {
    105      if (p==1) return false;
    106      int newp=p-1;
    107      if (!ma[v*10+newp])
    108      {
    109                         ma[v*10+newp]=true;
    110                         que.push(state(v*10+newp,s+1));
    111      }
    112      return false;
    113 }
    114 
    115 bool work6(int v,int p,int s)
    116 {
    117      if (p==6) return false;
    118      int newp=p+1;
    119      if (!ma[v*10+newp])
    120      {
    121                         ma[v*10+newp]=true;
    122                         que.push(state(v*10+newp,s+1));
    123      }
    124      return false;
    125 }
    126 int main()
    127 {
    128     scanf("%d%d",&s,&e);
    129     if (s==e)
    130     {
    131              printf("0\n");
    132              return 0;
    133     }
    134     shi[1]=1;
    135     for (int a=2;a<=6;a++)
    136     shi[a]=shi[a-1]*10;
    137     que.push(state(s*10+6,0));
    138     ma[s*10+6]=true;
    139     while (que.size())
    140     {
    141           state now=que.front();
    142           que.pop();
    143           int v=now.v / 10;
    144           int p=now.v % 10;
    145           if (work1(v,p,now.step)) break;
    146           if (work2(v,p,now.step)) break;
    147           if (work3(v,p,now.step)) break;
    148           if (work4(v,p,now.step)) break;
    149           if (work5(v,p,now.step)) break;
    150           if (work6(v,p,now.step)) break;
    151     }
    152     
    153     return 0;
    154 }
     
  • 相关阅读:
    B
    A
    P1057 传球游戏
    P1702 突击考试
    P1394 山上的国度
    P2117 小Z的矩阵
    P1510 精卫填海
    P1294 高手去散步
    P1071 潜伏者
    保留
  • 原文地址:https://www.cnblogs.com/zhonghaoxi/p/2518528.html
Copyright © 2011-2022 走看看