• UESTC_魔法少女小蟹 CDOJ 710


    小蟹是一名魔法少女,能熟练的施放很多魔法。

    有一天魔法学院上课的时候出现了这样一道题,给一个6位数,让大家用自己的魔法,把这个6位数变成另一个给定的6位数。

    小蟹翻了下魔法书,发现她有以下6种魔法:

    1. 将当前魔杖指向的数字与最左端的一个数字调换位置。

    2. 将当前魔杖指向的数字与最右端的一个数字调换位置。

    3. 将当前魔杖指向的数字+1。(若当前魔杖指向的数字为9则无效)

    4. 将当前魔杖指向的数字1。(若当前魔杖指向的数字为0则无效)

    5. 将当前魔杖向右移动一位。

    6. 将当前魔杖向左移动一位。

    最开始,她的魔杖指向的是最左边的数字。

    于是小蟹很好奇,以她的能力,施展几次魔法能完成老师的这道题呢?

    Input

    多组数据,请处理至文件结束(EOF)

    对于每组数据,包含两个6位数,a,b

    Output

    对于每组数据,输出一个数,代表最少施展魔法的次数。

    Sample input and output

    Sample InputSample Output
    123456 654321
    11

    解题报告

    不好想。。肯定不能处理操作3和操作4,那样bfs直接爆炸。。。本题连A*也不行。。因为状态数实在太多,又是多Case。。

    难保不TLE,因此我们预处理出魔杖能到达地方的状态,之后扫一遍所有状态,加上差值就完辣

      1 #include <iostream>
      2 #include <algorithm>
      3 #include <cstring>
      4 #include <cstdio>
      5 using namespace std;
      6 
      7 const int MaxHashSize = 1526597;
      8 const int MaxStatusSize = 5000000;
      9 typedef struct status
     10 {
     11 int step,value;    
     12 bool arrive[6];
     13 };
     14 
     15 
     16 int Head[MaxHashSize];
     17 int Next[MaxStatusSize];
     18 status st[MaxStatusSize];
     19 int caculate[7] = {1000000,100000,10000,1000,100,10,1};
     20 int tar_num[6];
     21 
     22 void Hash_init()
     23 {
     24  memset(Head,-1,sizeof(Head));    
     25 }
     26 
     27 int GetHashNum(int& x)
     28 {
     29  return x % MaxHashSize;    
     30 }
     31 
     32 bool insert_Hash(int id)
     33 {
     34  int h = GetHashNum(st[id].value);
     35  int t = Head[h];
     36  while(t != -1)
     37  {
     38      if(st[id].value == st[t].value)
     39       return false;
     40     t = Next[t];
     41  }
     42  Next[id] = Head[h];
     43  Head[h] = id;    
     44  return true;
     45 }
     46 
     47 
     48 
     49 int bfs()
     50 {
     51  int front = 0,rear = 1;
     52  insert_Hash(0);
     53  while(front < rear)
     54   {
     55       status ss = st[front++];
     56       int num[7];
     57       int ori = ss.value;
     58       for(int i = 6 ; i >=0 ; --i)
     59         {
     60           num[i] = ss.value % 10;
     61         ss.value /= 10; 
     62        }
     63     int pos = num[6];
     64     bool flag = true;
     65     if (num[pos] == 0 || pos == 0) flag = false;
     66     if (flag)
     67      {  
     68         st[rear] = ss;
     69          int temp = num[0];
     70          num[0] = num[pos];
     71          num[pos] = temp;
     72          int value = 0;
     73          for(int i = 0 ; i < 7 ; ++ i)
     74           value += (num[i]*caculate[i]);
     75            st[rear].value = value;        
     76            if (insert_Hash(rear))
     77               {
     78                   st[rear].step = ss.step + 1;
     79                   st[rear++].arrive[0] = true;
     80               }                       
     81              num[pos] = num[0];
     82              num[0] = temp;
     83      }
     84    flag = true;
     85    if (num[5]  == 0 && pos == 0) flag = false;
     86    if (pos == 5) flag = false;
     87    if (flag)
     88     {
     89           st[rear] = ss;
     90        int temp  = num[5];
     91        num[5] = num[pos];
     92        num[pos] = temp;
     93        int value = 0;
     94        for(int i = 0 ; i < 7 ; ++ i)
     95           value += (num[i]*caculate[i]);
     96            st[rear].value = value;
     97            if (insert_Hash(rear))
     98               {
     99                  st[rear].step = ss.step + 1;
    100                  st[rear++].arrive[5] = true;
    101              }                 
    102           num[pos] = num[5];
    103              num[5] = temp;
    104     }
    105    if (pos < 5)
    106     {
    107         st[rear] = ss;
    108         int value = ori + 1;
    109         st[rear].value = value;
    110         if (insert_Hash(rear))
    111          {
    112              st[rear].step = ss.step + 1;
    113             st[rear++].arrive[pos+1] = true;    
    114           }            
    115     }
    116    if (pos > 0)
    117     {
    118         st[rear] = ss;
    119         int value = ori - 1;
    120         st[rear].value = value;
    121         if (insert_Hash(rear))
    122          {
    123              st[rear].step = ss.step + 1;
    124              st[rear++].arrive[pos-1] = true;
    125           }           
    126     }
    127   }    
    128  return rear;
    129 }
    130 
    131 
    132 int slove(int x)
    133 {
    134  int Mo = 999;
    135  for(int i = 0 ; i < x; ++ i)
    136   {
    137       //cout << "i is " << i << endl;
    138       int num[6];
    139       st[i].value /= 10;
    140       int ori = st[i].value;
    141       for(int j = 5;j >=0 ;--j)
    142         {
    143           num[j] = st[i].value % 10;
    144           st[i].value /= 10;
    145        }
    146     int res = st[i].step;
    147     for(int k = 0 ; k < 6;++k)
    148      if (tar_num[k] != num[k] && !st[i].arrive[k])
    149       {
    150           res = 999;
    151           break;
    152       }
    153      else
    154      res += (abs(tar_num[k]-num[k]));
    155     //cout << "Res is " << res << endl;
    156     Mo = min(Mo,res);
    157   }
    158 return Mo;
    159 }
    160 
    161 
    162 int main(int argc, char * argv[])
    163 {
    164  int s1,s2;
    165  while(scanf("%d%d",&s1,&s2) == 2)
    166   {
    167       Hash_init();
    168       st[0].value = s1*10;
    169       st[0].step = 0;
    170       memset(st[0].arrive,false,sizeof(st[0].arrive));
    171       st[0].arrive[0] = true;
    172       for(int i = 5;i>=0;--i)
    173         {
    174            tar_num[i] = s2 % 10;
    175            s2 /= 10;
    176        }
    177       cout << slove(bfs()) << endl;
    178   }
    179  return 0;    
    180 }
    No Pain , No Gain.
  • 相关阅读:
    计蒜客 聪明的班主任(思维)
    codeforces 456 E. Civilization(并查集+数的直径)
    codeforces 456 D. A Lot of Games(字典数+博弈+思维+树形dp)
    codeforces 233 D. Table(思维+dp )
    codeforces 233 C. Cycles(贪心+思维)
    codeforces 814 D. An overnight dance in discotheque (贪心+bfs)
    codeforces 814 C. An impassioned circulation of affection(二分+思维)
    codeforces 813 D. Two Melodies(dp)
    Atcoder F
    Java正则表达式
  • 原文地址:https://www.cnblogs.com/Xiper/p/4467813.html
Copyright © 2020-2023  润新知