zoukankan      html  css  js  c++  java
  • hanoi新汉诺塔

    问题描述

    给出三根柱子,从左到右为A柱,B柱,C柱,每根柱子上一开始有若干盘子,盘子也是三种类型,A类,B类,C类,现在每次可以从某根柱子最顶上上拿一个盘子移到另一根柱子的最顶上,问最少要几步操作才能保证A柱上都是A盘子,B柱上都是B盘子,C柱上都是C盘子?

    输入格式

    共三行,每行第一个数表示对应柱子上盘子的个数,后跟一个空格。

    第一行从左到右给出了A柱从下到上的盘子的种类。

    第二行给出了B柱上的盘子。

    第三行给出了C住上的盘子。

    输出格式

    一个数,表示最小移动次数。

    样例输入

    1 A

    2 AA

    2 AA

    样例输出

    4

    数据范围

    盘子总个数≤10,保证一定可以通过若干步完成任务。

    题解

    把三根柱子的状态合成一个字符串,用1表示‘A’,2表示‘B’,3表示‘C’,用四进制存储状态,每根柱子10位,三根柱子30位,最大就430,用long long可以存。

    状态不是很多,广搜+哈希判重就可以了

      1 #include <cstdio>
      2 #define ll long long
      3 const int maxn=1e6+3;
      4 struct node{
      5     ll a,b,c;
      6     int d;
      7     node(ll a=0,ll b=0,ll c=0,int d=0):a(a),b(b),c(c),d(d){ }
      8 }q[1000005],ans;
      9 struct note{
     10     ll v;
     11     int nex;
     12 }g[1000005];
     13 int n,num,fir[1000003],cnt[5],h,t;
     14 char s[15];
     15 bool operator == (node x,node y)
     16 {
     17     return x.a==y.a && x.b==y.b && x.c==y.c;
     18  } 
     19 void add(ll x)
     20 {
     21     int y,k;
     22     for (y=x%maxn,k=fir[y];k;k=g[k].nex)
     23       if (g[k].v==x) return;
     24     g[++num].v=x;  g[num].nex=fir[y];  fir[y]=num;
     25     return;
     26 }
     27 bool vis(ll x)
     28 {
     29     for (int y=x%maxn,k=fir[y];k;k=g[k].nex)
     30       if (g[k].v==x) return 1;
     31     return 0;
     32 }
     33 int main()
     34 {
     35     int i,j;
     36     scanf("%d",&n);
     37     if (n) scanf("%s",s+1);
     38     for (i=1;i<=n;i++)
     39       q[1].a=(q[1].a<<2)|(s[i]-'A'+1),
     40       cnt[s[i]-'A'+1]++;
     41     scanf("%d",&n);
     42     if (n) scanf("%s",s+1);
     43     for (i=1;i<=n;i++)
     44       q[1].b=(q[1].b<<2)|(s[i]-'A'+1),
     45       cnt[s[i]-'A'+1]++;
     46     scanf("%d",&n);
     47     if (n) scanf("%s",s+1);
     48     for (i=1;i<=n;i++)
     49       q[1].c=(q[1].c<<2)|(s[i]-'A'+1),
     50       cnt[s[i]-'A'+1]++;
     51     q[1].d=0;
     52     for (i=1;i<=cnt[1];i++) ans.a=(ans.a<<2)|1;
     53     for (i=1;i<=cnt[2];i++) ans.b=(ans.b<<2)|2;
     54     for (i=1;i<=cnt[3];i++) ans.c=(ans.c<<2)|3;
     55     h=0;  t=1;
     56     add((q[1].a<<40)|(q[1].b<<20)|q[1].c);
     57     node u,v;
     58     while (h!=t)
     59     {
     60         u=q[++h];
     61         if (u.a)
     62         {
     63             v=u;
     64             v.b=(v.b<<2)|(v.a&3);
     65             v.a>>=2;
     66             if (!vis((v.a<<40)|(v.b<<20)|v.c))
     67               add((v.a<<40)|(v.b<<20)|v.c),
     68               q[++t]=node(v.a,v.b,v.c,u.d+1);
     69             if (v==ans)
     70             {
     71                 printf("%d",q[t].d);
     72                 return 0;
     73             }
     74             v=u;
     75             v.c=(v.c<<2)|(v.a&3);
     76             v.a>>=2;
     77             if (!vis((v.a<<40)|(v.b<<20)|v.c))
     78               add((v.a<<40)|(v.b<<20)|v.c),
     79               q[++t]=node(v.a,v.b,v.c,u.d+1);
     80             if (v==ans)
     81             {
     82                 printf("%d",q[t].d);
     83                 return 0;
     84             }
     85         }
     86         if (u.b)
     87         {
     88             v=u;
     89             v.a=(v.a<<2)|(v.b&3);
     90             v.b>>=2;
     91             if (!vis((v.a<<40)|(v.b<<20)|v.c))
     92               add((v.a<<40)|(v.b<<20)|v.c),
     93               q[++t]=node(v.a,v.b,v.c,u.d+1);
     94             if (v==ans)
     95             {
     96                 printf("%d",q[t].d);
     97                 return 0;
     98             }
     99             v=u;
    100             v.c=(v.c<<2)|(v.b&3);
    101             v.b>>=2;
    102             if (!vis((v.a<<40)|(v.b<<20)|v.c))
    103               add((v.a<<40)|(v.b<<20)|v.c),
    104               q[++t]=node(v.a,v.b,v.c,u.d+1);
    105             if (v==ans)
    106             {
    107                 printf("%d",q[t].d);
    108                 return 0;
    109             }
    110         }
    111         if (u.c)
    112         {
    113             v=u;
    114             v.a=(v.a<<2)|(v.c&3);
    115             v.c>>=2;
    116             if (!vis((v.a<<40)|(v.b<<20)|v.c))
    117               add((v.a<<40)|(v.b<<20)|v.c),
    118               q[++t]=node(v.a,v.b,v.c,u.d+1);
    119             if (v==ans)
    120             {
    121                 printf("%d",q[t].d);
    122                 return 0;
    123             }
    124             v=u;
    125             v.b=(v.b<<2)|(v.c&3);
    126             v.c>>=2;
    127             if (!vis((v.a<<40)|(v.b<<20)|v.c))
    128               add((v.a<<40)|(v.b<<20)|v.c),
    129               q[++t]=node(v.a,v.b,v.c,u.d+1);
    130             if (v==ans)
    131             {
    132                 printf("%d",q[t].d);
    133                 return 0;
    134             }
    135         }
    136     }
    137     return 0;
    138 }
  • 相关阅读:
    共用体
    位运算符和位运算
    python中while循环
    c语言中求多个整数的和及其平均值
    c语言中switch语句
    python中删除列表中多次重复的元素
    python中while循环
    python中break语句
    使用用户输入来填充字典
    python中while循环使用标志
  • 原文地址:https://www.cnblogs.com/rabbit1103/p/9882015.html
Copyright © 2011-2022 走看看