noip普及组2007 Hanoi双塔问题

时间:2023-03-09 15:12:49
noip普及组2007 Hanoi双塔问题

Hanoi双塔问题

描述

给定A,B,C三根足够长的细柱,在A柱上放有2n个中间有孔的圆盘,共有n个不同的尺寸,每个尺寸都有两个相同的圆盘,注意这两个圆盘是不加区分的。现要将这些圆盘移到C柱上,在移动过程中可放在B柱上暂存。要求:

(1)每次只能移动一个圆盘;

(2) A、B、C三根细柱上的圆盘都要保持上小下大的顺序;

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

格式

输入格式

输入为一个正整数n,表示在A柱上放有2n个圆盘。

输出格式

输出文件hanoi.out仅一行,包含一个正整数,为完成上述任务所需的最少移动次数An。

样例1

样例输入1

1

样例输出1

2

样例2

样例输入2

2

样例输出2

6

限制

1s

提示

对于50%的数据, 1<=n<=25

对于100% 数据, 1<=n<=200

提示:设法建立An与An-1的递推关系式。

其实就是高精度,公式:2^(n+1)-2

#include <iostream>
#include <algorithm>
using namespace std;
//ifstream cin("hanoi.in",ios :: in);
//ofstream cout("hanoi.out",ios :: out);
int main() {
  ios :: sync_with_stdio(false); //流的加速
  int n,len = 1,num[101];
  fill(num+1,num+100+1,0);
  num[1] = 1;
  len = 2;
  cin >> n;
  n++;
  while (n--) {  //*2操作
    for (int i = 1;i <= len;i++) num[i] *= 2;
    for (int i = 1;i <= len;i++)
      if (num[i] >= 10) {  //进位
        num[i+1] += num[i]/10;
        num[i] %= 10;
      }
    if(num[len] != 0) len++;
  }
  num[1] -= 2;  //-2操作
  for (int i = 1;i < len;i++) {
    if (num[i] < 0) {  //退位
      num[i+1] -= 10;
      num[i] += 10;
    }
  }
  if (num[len] < 0) len--;
  for (int i = len-1;i >= 1;i--) cout << num[i];  //输出
  return 0;
}