P1096

[NOIP2007 普及组] Hanoi 双塔问题

题目描述

给定 A、B、C 三根足够长的细柱,在 A 柱上放有 \(2n\) 个中间有孔的圆盘,共有 \(n\) 个不同的尺寸,每个尺寸都有两个相同的圆盘,注意这两个圆盘是不加区分的(下图为 \(n=3\) 的情形)。

现要将这些圆盘移到 C 柱上,在移动过程中可放在 B 柱上暂存。要求:

  1. 每次只能移动一个圆盘;
  2. A、B、C 三根细柱上的圆盘都要保持上小下大的顺序。

任务:设 \(A_n\)\(2n\) 个圆盘完成上述任务所需的最少移动次数,对于输入的 \(n\),输出 \(A_n\)

输入格式

一个正整数 \(n\),表示在 A 柱上放有 \(2n\) 个圆盘。

输出格式

一个正整数, 为完成上述任务所需的最少移动次数 \(A_n\)

样例 #1

样例输入 #1

1

样例输出 #1

2

样例 #2

样例输入 #2

2

样例输出 #2

6

提示

【限制】

  • 对于 \(50\%\) 的数据,\(1 \le n \le 25\)
  • 对于 \(100\%\) 的数据,\(1 \le n \le 200\)

【提示】

设法建立 \(A_n\)\(A_{n-1}\) 的递推关系式。

代码如下

#include <bits/stdc++.h>
using namespace std;

int main() {
	int n;
	cin >> n;
	int a[200];
	memset(a,0,sizeof a); 
	a[0] = 2;
	int t = 0; //最高位
	 

	for (int j = 0; j < n; j++) {
		int k = 0;
		//翻倍 
		for (int i = 0; i <= t; i++)
			a[i] *= 2;
		//进位 
		for (int i = 0; i <= t; i++) {
			if (a[i] >= 10) {
				a[i] %= 10;
				a[i + 1]++;
				if (i == t)
					t++;
			}
		}
	}
	 
	//最高位大于10 进位 
	if (a[t] >= 10) {
		a[t] %= 10;
		t++;
		a[t] = 1;
	}
	//减去2 
	int t1 = 2;
	if (a[0] >= 2) {
		a[0] -= 2;
	} else {
		//找到大于1的最小位 
		int k = 1;
		while (a[k] < 1) {
			a[k] = 9;
			k++;
		}
		a[k] -= 1;
		//如果减去的是最高位且减去后最高位为0则最高位往后退一位 
		if(k==t&&a[k]==0){
			t--;
		}
	}
	
	for (int i = t; i >= 0; i--)
		cout << a[i];
	return 0;
}
posted @ 2023-11-02 10:09  hey在干嘛  阅读(19)  评论(0)    收藏  举报