您的位置:首页 > 编程语言 > C语言/C++

[NOIP2007] Hanoi双塔问题-解题报告

2016-10-13 21:23 519 查看

[NOIP2007] Hanoi双塔问题

时间限制:1 s 内存限制:128 MB

问题描述

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

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

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

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

输入

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

输出

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

输入输出样例1

hanoi.in

1

hanoi.out

2

输入输出样例2

hanoi.in

2

hanoi.out

6

限制

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

对于100%的数据,l<=n<=200

提示

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

题目分析

汉诺塔问题, 有递推式 f(n+1)=f(n)*2+1

本题还需要高精度计算,在此贴出我自己编写的高精度模板,不保证正确

#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;

const int N=200+10;

struct Bign{
static const int N = 100000,M = 1;
static const int powm = 10;// powm = pow(10,M);
int a
;
// bool_type;
bool operator < (const Bign &num) const {
if(a[0] != num.a[0])return a[0] < num.a[0];
const int *b = num.a;
int th = a[0];
while(a== b&& th > 0) th--;
return a< b;
}
bool operator > (const Bign &num) const {return num < *this;}
bool operator <= (const Bign &num) const {return !(num < *this);}
bool operator >= (const Bign &num) const {return !(num > *this);}
bool operator != (const Bign &num) const {return num < *this  || num > *this;}
bool operator == (const Bign &num) const {return !(num != *this);}
// =_type;
Bign operator = (int num){
memset(a,0,sizeof(a));
while(num){
a[++a[0]] = num % powm;
num /= powm;
}
return *this;
}
Bign (int num = 0){*this = num;}
// +_type;
Bign operator + (const Bign &num) const {
Bign ret = 1;
const int *b = num.a;
int *c = ret.a, buf = 0;
for(int &i = c[0]; i <= max(a[0], b[0]) || buf; i++){
c[i] = a[i] + b[i] + buf;
buf = c[i] / powm;
c[i] %= powm;
}c[0]--;
return ret;
}Bign operator += (const Bign &num) const {return *this + num;}

Bign operator + (const int num) const {
Bign ret = num;
return *this + ret;
}Bign operator += (const int num) const {return *this + num;}
// -_type;
Bign operator - (const Bign &num) const {
if(a <
4000
num.a) return num - *this;
Bign ret = 1;
const int *b = num.a;
int *c = ret.a, buf = 0;
for(int &i = c[0]; i < a[0] || a[i] + buf; i++){
c[i] = a[i] + powm - b[i] + buf;
buf = c[i] / powm - 1;
c[i] %= powm;
}
while((!c[c[0]])&&c[0]>0)c[0]--;
return ret;
}Bign operator -= (const Bign &num) const {return *this - num;}

Bign operator - (const int num) const {
Bign ret = num;
return *this - ret;
}Bign operator -= (const int num) const {return *this - num;}
// *_type;
Bign operator * (const Bign &num) const {
Bign ret;
const int *b = num.a;
int *c = ret.a;
for(int i = 1; i <= b[0]; i++){
int buf = 0;
for(int j = 1; j <= a[0] || buf; j++){
c[i+j-1] += a[j] * b[i] + buf;
buf = c[i+j-1] / powm;
c[i+j-1] %= powm;
}
}c[0] = a[0] + b[0];
if(!c[c[0]]) c[0]--;
return ret;
}Bign operator *= (const Bign &num) const {return *this * num;}

Bign operator * (const int num) const {
Bign ret = num;
return *this * ret;
}Bign operator *= (const int num) const {return *this * num;}
// /_type;
Bign operator / (const int num) const {
Bign ret = 1;
int *c = ret.a, buf = 0;
for(int i = a[0]; i > 0; i--){
buf = buf * powm + a[i];
c[i] = buf / num;
buf %= num;
}c[0] = a[0];
for(int &i = c[0]; !c[i]; i--);
buf = 0;
for(int i = 1; i <= c[0] || buf; i++){
c[i] += buf;
buf = c[i] / powm;
}
return ret;
}Bign operator /= (const int num) const {return *this - num;}
// sqrt;
friend Bign sqrt (const Bign&);
// io;
void in () {
*this = 0;
a[0] = 1;
//      int *a = this -> a;
char buf;
bool brea=0;
for(int &i = a[0]; !brea; i++){
for(int j = 1; j <= M; j++){
buf = getchar();
if(buf < '0' || buf > '9')
{brea = 1; break;}
a[i] += (buf - '0') * pow(10, j - 1);
}
}a[0]-=2;
int l=1,r=a[0];
while(l<r){
int buf=a[l];
a[l]=a[r];
a[r]=buf;
l++; r--;
}
}
void out () {
int *a = this -> a;
for(int i = a[0]; i > 0; i--)
printf("%d", a[i]);
if(a[0]==0)putchar('0');
}
};

Bign sqrt (const Bign &num){
Bign l = 1, r = num;
Bign mid, buf;
while(l < r){
mid = (r + l) / 2;
buf = mid * mid;
if(buf == num) break;
if(buf >= num) r = mid;
else l = mid + 1;
}l=l-1;
return l;
}

Bign d;

int main()
{
freopen("hanoi.in","r",stdin);
freopen("hanoi.out","w",stdout);
int n;
scanf("%d",&n);
d=1;
for(int i=2;i<=n;i++)
d=d+d+1;
d=d+d;
d.out();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息