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 }