C語言實現 藍橋杯 算法提高 漢諾塔

試題 算法提高 漢諾塔

                                                                                  藍橋杯試題解答彙總鏈接

資源限制

       時間限制:1.0s 內存限制:256.0MB


問題描述

       漢諾塔是一個古老的數學問題:
  有三根杆子A,B,C。A杆上有N個(N>1)穿孔圓盤,盤的尺寸由下到上依次變小。要求按下列規則將所有圓盤移至C杆:
  每次只能移動一個圓盤;
  大盤不能疊在小盤上面。
  提示:可將圓盤臨時置於B杆,也可將從A杆移出的圓盤重新移回A杆,但都必須遵循上述兩條規則。

問:如何移?最少要移動多少次?


輸入格式

       一行,包含2個正整數,一個是N,表示要移動的盤子數;一個是M,表示最少移動步數的第M步


輸出格式

       共2行。
  第一行輸出格式爲:#No: a->b,表示第M步驟具體移動方法,其中No表示第M步移動的盤子的編號(N個盤子從上到下依次編號爲1到n),表示第M步是將No號盤子從a杆移動到b杆(a和b的取值均爲{A、B、C})。
  第2行輸出一個整數,表示最少移動步數。


樣例輸入

2

樣例輸出

#2: A->B
7

數據規模與約定

0<N<20,0<M<=最少移動步數

試題解析

下面舉例的3種情況如不好理解建議跟着思路自己畫圖理解!
假設n=1:那麼直接需要一步把第1個(即第n個)從A移到C即:#1: A->C共1步
假設n=2:那麼需要把第1個(即第n-1個)從A移動到B;在把第2個(即第n個)移動到C;然後把第1個(即第n-1個)從B移動到C即#2: A->B,#1: A->C,#2: B->C共3步
假設n=3:那麼需要先把第1個(即第n-2個)從A移動到C然後把第2個(即第n-1個)從A移動到B然後把第1個(即第n-2個)從C移動到B然後把第3個(即第n個)從A移到C然後把第1個(即第n-2個)從B移到A然後把第2個(即第n-1個)從B移到C然後把第1個(即第n-1個)從A移到C即:#1: A->C,#2: A->B,#1: C->B,#3: A->C,#1: B->A,#2: B->C,#1: A->C共7步
總結規律:先假設f(n)爲把n個盤子從一根柱子全部移動到另外一根柱子所需要的最少步數。要想實現f(n)需要分三步如下圖在這裏插入圖片描述
要實現f(n-1)有可以按照f(n)的思路分爲三個步驟,這就是遞歸的思路,根據這個可以總結出一個等式f(n+1)=2f(n)+1(n爲任意的正整數)即
f(n+1)+1=2(f(n)+1)又f(n)>0所以數列f(n)+1爲以2爲首項2爲公比的等比數列
可以求出f(n)=2n-1
但題目不僅要求最少的步數還要求給出第m步的操作過程,所以我們需要根據上面的分三步思路定義新的函數Hanoi(n,A,B,C),它表示的意思是把在A的n塊通過B的輔助移動到C(不通過C在n-1大於2時是無法直接移動到B的)那麼根據上面的三步走可以如此遞歸
要實現Hanoi(n,A,B,C)
先得實現Hanoi(n-1,A,C,B)即把在A的n-1塊通過C的輔助移動到B
然後A上只剩下第n塊所以把第n個從A移動到C即:#n: A->C
然後實現Hanoi(n-1,B,A,C)即把在B的n-1塊通過A的輔助移動到C
在添加一個計步器count在第m步時輸出即可


代碼

#include<stdio.h>
// n,m對應題意,count是計步器 
int n,m,count=0;
/**
 * 在只有一塊的情況下直接把這一塊從A移到C不需要藉助B
 * 1.要把n個盤子藉助B移到C就先要把n-1個在A的盤子藉助C移到B
 * 2.現在n-1個盤子在B,就把第n個從A移到C
 * 3.然後把n-1個在B上的盤子藉助A移動到C 
 */
void Hanoi(int n,char A,char B,char C){
	if(n==1){
		count++;
		if(count==m){
			printf("#%d: %c->%c\n",n,A,C);
		}
		return;
	}
	Hanoi(n-1,A,C,B);
	count++;
	if(count==m){
		printf("#%d: %c->%c\n",n,A,C);
	}
	Hanoi(n-1,B,A,C);
}
int main(){
	scanf("%d%d",&n,&m);
	/**
	 * 先要把n個在A上的盤子藉助B放到C 
	 */
	Hanoi(n,'A','B','C');
	printf("%d",count);
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章