HDOJ 1997ハノータVII(再帰シミュレーションor法則解法)
3668 ワード
ハノータVII
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 1358 Accepted Submission(s): 891
Problem Description
n個の皿のハノータ問題の最小移動回数は2^n−1であり,すなわち移動中に2^n個の系列が生じる.ずれが発生したシリーズが増加したため、この誤りは柱を間違えたことであり、大皿を小皿に置くことはない.すなわち、各柱の下から上への大きさは以下の関係を維持している.n=m+p+q a 1>a 2>...>am b 1>b 2>...>bp c 1>c 2>...>cq aiはA柱上の盤の盤番号シリーズであり、biはB柱上の盤番号シリーズであり、ciはC柱上の盤番号シリーズである.最初はAカラム上のn個の皿をCディスクに移すことを目標とし,正しい移動で発生したシリーズであるか否かを判断する1系列を与えた.例1:n=3 3 2 1が正しい例2:n=3 3 1 2が正しくない.注:例2において、A柱上のn個の皿をB皿に移すことが目標である場合は、正しい.
Input
複数組のデータを含み、まずTを入力し、T組のデータがあることを示す.各組のデータ4行、第1行Nは皿の数N<=64.後3行は以下のようにm a 1 a 2...am pb 1 b 2...bp q c 1 c 2...cqN=m+p+q,0<=m<=N,0<=p<=N,0<=q<=N,
Output
各グループのデータについて、正しい移動で発生したシリーズかどうかを判断します.trueを正しく出力します.そうしないとfalse
Sample Input
Sample Output
问题解:题目はとても良くて、ハノータの移动の规则の学友に熟知していないで、どうぞ入って、ドアを転送します:普普普のブログ
2つの解法がある.
一、再帰シミュレーション法:
ハンノタワーの移動を再帰的にシミュレートし,与えられた状態が3本目の柱にすべて移動できるかどうかを判断した.
①最大皿n号皿を考えると、移動方向はA-->Cで、AまたはCにしかありません.Bにあればfalseです.
②n号皿がAにある場合、その上のn-1号皿は必ずA——>Bからの移動中であり、このとき最大皿番号はn-1であり、移動方向はA—>Bである.
③n号皿がC上にある場合、その上のn-1号皿は必ずB-->Cからの移動中であり、このとき最大皿番号はn-1であり、移動方向はB—>Cである.
④①②③を繰り返す.
コードは次のとおりです.
法則解法:
上のハンノタワーモデルの移動過程を通して,いくつかの法則を発見することができる.
①盤が奇数の場合、一番下が偶数の場合は2番柱のみ、一番下が奇数の場合は1,3番柱のみ
②偶数は上と反対
③各柱の皿はパリティ交換
コードは次のとおりです.
ハノータVII
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 1358 Accepted Submission(s): 891
Problem Description
n個の皿のハノータ問題の最小移動回数は2^n−1であり,すなわち移動中に2^n個の系列が生じる.ずれが発生したシリーズが増加したため、この誤りは柱を間違えたことであり、大皿を小皿に置くことはない.すなわち、各柱の下から上への大きさは以下の関係を維持している.n=m+p+q a 1>a 2>...>am b 1>b 2>...>bp c 1>c 2>...>cq aiはA柱上の盤の盤番号シリーズであり、biはB柱上の盤番号シリーズであり、ciはC柱上の盤番号シリーズである.最初はAカラム上のn個の皿をCディスクに移すことを目標とし,正しい移動で発生したシリーズであるか否かを判断する1系列を与えた.例1:n=3 3 2 1が正しい例2:n=3 3 1 2が正しくない.注:例2において、A柱上のn個の皿をB皿に移すことが目標である場合は、正しい.
Input
複数組のデータを含み、まずTを入力し、T組のデータがあることを示す.各組のデータ4行、第1行Nは皿の数N<=64.後3行は以下のようにm a 1 a 2...am pb 1 b 2...bp q c 1 c 2...cqN=m+p+q,0<=m<=N,0<=p<=N,0<=q<=N,
Output
各グループのデータについて、正しい移動で発生したシリーズかどうかを判断します.trueを正しく出力します.そうしないとfalse
Sample Input
6 3 1 3 1 2 1 1 3 1 3 1 1 1 2 6 3 6 5 4 1 1 2 3 2 6 3 6 5 4 2 3 2 1 1 3 1 3 1 2 1 1 20 2 20 17 2 19 18 16 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
Sample Output
true false false false true true
问题解:题目はとても良くて、ハノータの移动の规则の学友に熟知していないで、どうぞ入って、ドアを転送します:普普普のブログ
2つの解法がある.
一、再帰シミュレーション法:
ハンノタワーの移動を再帰的にシミュレートし,与えられた状態が3本目の柱にすべて移動できるかどうかを判断した.
①最大皿n号皿を考えると、移動方向はA-->Cで、AまたはCにしかありません.Bにあればfalseです.
②n号皿がAにある場合、その上のn-1号皿は必ずA——>Bからの移動中であり、このとき最大皿番号はn-1であり、移動方向はA—>Bである.
③n号皿がC上にある場合、その上のn-1号皿は必ずB-->Cからの移動中であり、このとき最大皿番号はn-1であり、移動方向はB—>Cである.
④①②③を繰り返す.
コードは次のとおりです.
#include<cstdio>
#include<cstring>
using namespace std;
void input(int n,int *a)
{
int i;
memset(a,0,65*sizeof(int));// sizeof(a)
for(i=0;i<n;++i)
scanf("%d",&a[i]);
}
bool move(int n,int *a,int *b,int *c)//
{
if(n==0)
return true;
if(n==a[0])// n A , n-1 ( n ) C B
return move(n-1,++a,c,b);
else if(n==c[0])// n C , n-1 B ( n ) A C
return move(n-1,b,a,++c);
return false;
}
int main()
{
int t,i,m,q,p,n;
int a[65],b[65],c[65];
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
scanf("%d",&m);
input(m,a);
scanf("%d",&q);
input(q,b);
scanf("%d",&p);
input(p,c);
if(move(n,a,b,c))
printf("true
");
else
printf("false
");
}
return 0;
}
法則解法:
上のハンノタワーモデルの移動過程を通して,いくつかの法則を発見することができる.
①盤が奇数の場合、一番下が偶数の場合は2番柱のみ、一番下が奇数の場合は1,3番柱のみ
②偶数は上と反対
③各柱の皿はパリティ交換
コードは次のとおりです.
#include<cstdio>
#include<cstring>
#define maxn 65
using namespace std;
int a[3][maxn],n;
bool solve()
{
int i,j;
for(i=0;i<3;++i)
{
if(a[i][0]==0)
continue;
if((n+i+a[i][1])%2)// , , 1,3, ;
return false;
for(j=2;j<=a[i][0];++j)//
{
if((a[i][j]+a[i][j-1])%2==0)
return false;
}
}
return true;
}
int main()
{
int i,t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(i=0;i<3;++i)
{
scanf("%d",&a[i][0]);
for(int j=1;j<=a[i][0];++j)
scanf("%d",&a[i][j]);
}
if(solve())
printf("true
");
else
printf("false
");
}
return 0;
}