ハノイの塔問題のまとめ(1)

  1. まず、知っておく必要があります。プレートがn個あるハノイの塔の場合、移動の最小数は(2 ^ n-1)であり、移動中に2n乗の異なる状態が発生します。
  2. 例1:

タイトルの説明:
n枚のプレートを使用したTower ofHanoi問題の最小移動数は2 ^ / n-1です。つまり、移動中に2n番目の電力系列が生成されます。
ミスアライメントによるシリーズの数が増えています。この種のエラーは、カラムの位置ずれであり、大きなプレートを小さなプレートに配置しません。つまり
各カラムの下部から上部までのサイズは、次の関係を維持します
。n= m + p + q
a1> a2>…> am
b1> b2>…> bp
c1> c2>…> cq
生成されるすべてのシリーズの総数を計算します。


入力:
データの複数のセットを含み、第一Tを入力し、データのTセットがあることを意味しているデータの各ライン番号である。
プレートN <30。
3
1
3
29


出力:
データのグループごとに、移動中に生成されたシリーズの総数を出力します。
3
27
68630377364883

  • 思考:n個のプレート全体に対して、3つの状態があります。(n-1)を取り出し、最大のプレートは3x2の状態になります。次に、(n-2)を取り出し続け、残りを追跡します。 2つは3x3x2の状態になります...など、次のコードを取得できます。
#include<iostream>
#include<cmath>
using namespace std;
 
int main()
{
    
    
	int t;
	cin>>t;
	while(t--)
	{
    
    
		int n;
		long long sum=3;
		cin>>n;
		for(int i=2;i<=n;i++)
			sum+=pow(3,i-1)*2;
		cout<<sum<<endl; 
	}
    return 0;
}
  1. 例2:

タイトルの説明:
プレートの数とプレートの1つの数、プレートが移動される最小回数を見つけます。


入力:
複数のデータセットが含まれています。最初にTを入力します。これは、Tセットのデータがあることを意味します。データの各行は、プレートの数N(1 <= N <= 60)とプレートの
数k(1 <= k <= N)です。
2
60 1
3 1


出力:
576460752303423488
4

  • 列挙により、n枚のプレートの下で、k番のプレートを移動する必要がある最小回数は2 ^(nk)であると結論付けることができます。最も明白な例は、2の0乗である最大のシャーシです。ここで再帰を使用すると、60回あることを考えると、時間の消費が非常に長くなり、適切ではありません。コードは次のように表示されます。
#include<iostream>
#include<cmath>
using namespace std;
 
int main()
{
    
    
    int n,t,k;
    long long result;
    cin>>n;
    while(n--)
	{
    
    
        cin>>t>>k;
        result = pow(2,t-k);
        cout<<result<<endl;
    }
    return 0;
}
  1. 例3:

問題の説明:
ゲームのプレイ方法を変更し、左端(右)側から右端(左)側に直接移動しないようにします(すべての移動は中央のロッドに移動するか、中央から移動する必要があります)。また、市場を下に置くことはできません。ディスクの上部。現在、N枚のディスクがあります。これらのディスクを左端から右端に移動するには、何回移動する必要がありますか?


入力:
複数のデータセットが含まれ、毎回Nの値を入力します(1 <= N = 35)。
1
3
12


出力:
データのグループごとに、最小移動数を出力します。
2
26
531440

  • 思考:さらにいくつかのデータセットを記述し、法則を遵守することにより、最小移動数が正確に3 ^ n-1であることがわかります。したがって、コードは次のようになります。
#include<iostream>
#include<cmath>
using namespace std;

int main()
{
    
    
	int n;
	while(cin>>n)
	{
    
    
		long long sum=1;//这里要用long long,不然会溢出
		while(n--) sum*=3;
		cout<<sum-1<<endl; 
	}
	return 0;	
}
  1. 例4:

タイトルの説明:
左端(右)側から右端(左)側に直接移動することはできません(すべての移動を中央のロッドに移動するか、中央から削除する必要があります)。また、大きなディスクを小さなディスクの上に配置することはできません。最大のプレートを上に置くとどうなりますか?(一番上に置くことができるのは最大のものだけです)もちろん、最終的な結果は、プレートが小さいものから大きいものへと右端に配置されることです。


入力:
入力データの最初の行はデータTです。これは、Tグループのデータがあることを意味します。
データの各グループには正の整数n(1 <= n <= 20)があり、これはn個のプレートがあることを意味します。
2
1
10


出力:
入力データの各セットについて、必要な配置の最小数。
2
19684

  • データを観察することにより、最小回数は3 ^(n-1)+1の法則を満たしていると結論付けることができ、次のコードを取得できます。
#include<iostream>
using namespace std;

int main()
{
    
    
	int t;
	cin>>t;
	while(t--)
	{
    
    
		int n;
		cin>>n;
		long long sum=1;
		n--;
		while(n--) sum*=3;
		cout<<sum+1<<endl;
	}
	return 0;	
}

おすすめ

転載: blog.csdn.net/weixin_45688536/article/details/105275566