写这篇博客是因为暑假的时候做湖大训练赛的时候就做过一个类似的题,当时还想了很久到底怎么写才好, 今天再碰到这题的时候发现我之前写的好麻烦
方法:
汉诺塔本身就是个递推,所以你判断当前情况是否存在,只需要判断是否符合递推式即可
例如初始n个盘都在A柱,且目标是将这n个盘由A至C,递推中进行的操作为先将n-1个盘推到B,然后再将第n个盘推到C
所以第n个盘只能在AorC, 当第n个盘在A时,还在进行的的操作为将前n-1个盘推到B,所以同理可得第n-1个盘只能在AorB。 当第n个盘在C时,此时进行的操作为将前n-1个盘由B推到C,所以第n-1个盘只能在B or C。
所以我们只需写一个递推即可。。。。
hdu 1997 代码:
#include <cstdio>
#include <cstring>
#define maxn 70
int A[maxn];
int ans;
void dfs(int a, int b, int n)
{
if(!n || !ans)
return;
if(A[n]== a)
dfs(a, 6- a- b, n-1);
else if(A[n]== b)
dfs(b, 6-a-b, n-1);
else
{
ans= 0;
return;
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
memset(A, 0, sizeof(A));
int n, m, num;
scanf("%d",&n);
for(int j= 1; j<= 3; j++)
{
scanf("%d",&m);
for(int i= 1; i<= m; i++)
{
scanf("%d",&num);
A[num]= j;
}
}
ans= 1;
dfs(1, 3, n);
if(ans)
printf("true\n");
else
printf("false\n");
}
return 0;
}
做湖大那题时代码写的有点。。。
hnu 12867 代码:
#include <cstdio>
#include <cstring>
char s[255];
int n;
int ans;
void dfs(int d, char A, char B)
{
// printf("%d %c %c\n",d, A, B);
if(!d || !ans)
return;
char xx;
if(A!='C' && B!= 'C')
xx= 'C';
else if(A!='B' && B!='B')
xx= 'B';
else if(A!='A' && B!='A')
xx= 'A';
if(s[d]==A)
dfs(d-1, A, xx);
else if(s[d]==B)
dfs(d-1, xx, B);
else
{
ans= 0;
return;
}
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
scanf("%s",s+1);
ans= 1;
dfs(n, 'A', 'B');
if(ans)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}