[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.in1
hanoi.out
2
输入输出样例2
hanoi.in2
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; } 相关文章推荐
- noip普及组2007 Hanoi双塔问题
- 【NOIP2007】Hanoi双塔问题
- 【NOIP2007】第四题·Hanoi双塔问题
- 洛谷 P1096 RQNOJ P129 [NOIP普及组2007] Hanoi双塔问题
- noip2007 Hanoi双塔问题 (动态规划,汉诺塔问题,高精乘低精)
- 【数论】[NOIP2007]Hanoi双塔问题
- luogu1096 Hanoi双塔问题(NOIP2007普及组第4题)(高×低)
- NOIP2007普及组-Hanoi双塔问题
- NOIP 2007 普及组解题报告
- LuoguP2822[NOIP2016] 组合数问题 解题报告【组合数取模+矩阵前缀和】
- NOIP2007 T1奖学金 解题报告-S.B.S.
- NOIP 2007矩阵取数游戏 解题报告(区间型DP)
- NOIP2007 T1奖学金 解题报告-S.B.S.
- NOIP2007解题报告
- [NOIP2007] 字符串的展开-解题报告
- codevs 1164 || NOIP 2007 统计数字 模拟 解题报告
- NOIP2007 T1奖学金 解题报告-S.B.S.
- NOIP 1998 上下车问题 解题报告
- NOIP2007 T2纪念品分组 解题报告-S.B.S.
- COGS 25. [NOIP2007] 守望者的逃离 解题报告