寫這篇博客是因爲暑假的時候做湖大訓練賽的時候就做過一個類似的題,當時還想了很久到底怎麼寫纔好, 今天再碰到這題的時候發現我之前寫的好麻煩
方法:
漢諾塔本身就是個遞推,所以你判斷當前情況是否存在,只需要判斷是否符合遞推式即可
例如初始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;
}