首页 > 其他分享 >CSP历年复赛题-P1096 [NOIP2007 普及组] Hanoi 双塔问题

CSP历年复赛题-P1096 [NOIP2007 普及组] Hanoi 双塔问题

时间:2024-05-27 11:21:55浏览次数:10  
标签:NOIP2007 int res Hanoi long vector P1096 hanoi size

原题链接:https://www.luogu.com.cn/problem/P1096

题意解读:汉诺双塔的移动次数,与经典汉诺塔的区间在于同一个尺寸盘子有两个。

解题思路:

可以直接用经典汉诺塔方法来计算,双塔的结果就最终乘以2即可。

首先想到的是递归,但是由于数据量n最大200,递归会超时,但是50%的样例应该没问题,先拿分!

50分代码:

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

int ans;

void hanoi(int n)
{
    if(n == 1)
    {
        ans++; //只剩一个盘子,移动到目标柱子
        return;
    }
    hanoi(n-1); //移动前n-1个盘子都暂存柱子
    ans++; //移动第n个到目标柱子
    hanoi(n-1); //移动前n-1个到目标柱子
}

int main()
{
    int n;
    cin >> n;
    hanoi(n);
    cout << ans * 2; //双塔乘以2

    return 0;
}

根据提示,考虑采用递推,直接借助上面递归代码运行出

n = 1,输出2

n = 2,输出6

n = 3,输出14

n = 4,输出30

n = 5,输出62

我们观察一下2,6,14,30,62,可以推出递推式f[n] = f[n-1] * 2 + 2,初始值f[1] = 2,最终结果是f[n]

由于n最大是200,2^200用long long也无法存储,需要高精度

先写出以下代码,再替换高精度

70分代码:

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

long long f[205];

int main()
{
    int n;
    cin >> n;
    f[1] = 2;
    for(int i = 2; i <= n; i++)
    {
        f[i] = f[i-1] * 2 + 2;
    }
    cout << f[n];

    return 0;
}

加上高精度,只需要加法即可!

100分代码:

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

vector<int> f[205];
vector<int> g2(1, 2); //高精度的2

vector<int> add(vector<int> &a, vector<int> &b)
{
    vector<int> res;
    int t = 0;
    int len = max(a.size(), b.size());
    for(int i = 0; i < len; i++)
    {
        if(i < a.size()) t += a[i];
        if(i < b.size()) t += b[i];
        res.push_back(t % 10);
        t /= 10;
    }
    if(t) res.push_back(t);
    return res;
}

int main()
{
    int n;
    cin >> n;
    f[1] = g2;
    for(int i = 2; i <= n; i++)
    {
        vector<int> res = add(f[i-1], f[i-1]);
        f[i] = add(res, g2);
    }
    
    for(int i = f[n].size() - 1; i >= 0; i--) cout << f[n][i];

    return 0;
}

 

标签:NOIP2007,int,res,Hanoi,long,vector,P1096,hanoi,size
From: https://www.cnblogs.com/jcwy/p/18215141

相关文章

  • CSP历年复赛题-P1095 [NOIP2007 普及组] 守望者的逃离
    原题链接:https://www.luogu.com.cn/problem/P1095题意解读:在有限的时间内,通过跑步或者闪烁两种方式,能跑出的最远距离是多少,以及是否能跑出出口。解题思路:1、贪心法每一秒钟,都有两种选择:跑步(17米)、闪烁(60米,前提是蓝够10点,否则等待1s恢复4点蓝)经过计算,恢复足够的蓝到闪烁需要3.......
  • CSP历年复赛题-P1094 [NOIP2007 普及组] 纪念品分组
    原题链接:https://www.luogu.com.cn/problem/P1094题意解读:贪心选择解题思路:贪心策略:将纪念品按价格由小到大排序,优先一大、一小,如果价格之和不超限,则分为一组,如果超限,则大的单独分为一组,重复以上过程,直到所有数据都遍历到,采用一头一尾双指针即可。证明:如果最大价格不是和最......
  • 洛谷P1097 [NOIP2007 提高组] 统计数字
    #先看题目题目描述某次科研调查时得到了n 个自然数,每个数均不超过1.5×109。已知不相同的数不超过 个,现在需要统计这些自然数各自出现的次数,并按照自然数从小到大的顺序输出统计结果。输入格式共n+1 行。第一行是整数n,表示自然数的个数;第 2至n+1 每行一个自......
  • Hanoi问题及其相关快速算法
    Hanoi问题抽象hanoi(n,x,y,z)step1:hanoi(n-1,x,z,y)step2:move(x,z)step3:hanoi(n-1,y,x,z)递归部分实现代码voidhanoi(intn,charx,chary,charz){​ if(n==1){ // 递归出口​ move(x,z);​ }​ else{​ hanoi(n-1,x,z,y);​ move(x,z);​ hanoi(n......
  • 洛谷题单指南-贪心-P1094 [NOIP2007 普及组] 纪念品分组
    原题链接:https://www.luogu.com.cn/problem/P1094题意解读:贪心选择解题思路:贪心策略:将纪念品按价格由小到大排序,优先选择价格大的一直到超过分组价格上限,再选择价格小的直到超过价格上限,此为一组重复以上过程,直到所有数据都遍历到,采用一头一尾双指针即可。证明:如果最大价格......
  • P1093 [NOIP2007 普及组] 奖学金
    1.题目介绍[NOIP2007普及组]奖学金题目背景NOIP2007普及组T1题目描述某小学最近得到了一笔赞助,打算拿出其中一部分为学习成绩优秀的前\(5\)名学生发奖学金。期末,每个学生都有\(3\)门课的成绩:语文、数学、英语。先按总分从高到低排序,如果两个同学总分相同,再按语文成绩......
  • 洛谷题单指南-排序-P1093 [NOIP2007 普及组] 奖学金
    原题链接:https://www.luogu.com.cn/problem/P1093题意解读:本题考察排序,根据题意,先按总分从大到小排,再按语文从大到小排,以上都相同则按学号从小到大排。100分代码:#include<bits/stdc++.h>usingnamespacestd;constintN=305;structstudent{intid;intyuw......
  • 4147:汉诺塔问题(Tower of Hanoi)C++
    递归C和C++一样,就写个C++了。#include<iostream>usingnamespacestd;voidmove(intn,chara,charb,charc){if(n<=0)return;move(n-1,a,c,b);cout<<n<<":"<<a<<"->"<<c<<'\n�......
  • 洛谷题单指南-模拟和高精度-P1098 [NOIP2007 提高组] 字符串的展开
    原题链接:https://www.luogu.com.cn/problem/P1098题意解读:题目本身是一道模拟题,但是细节点较多,要拿100分,有以下注意点:1、-号两个需要同时为小写字母或者数字,才进行填充2、-号左边>=右边,直接输出-3、对待填充的内容的处理,可以先看是否填充*;小写字母和数字的填充都是前一位asci......
  • [NOIP2007 普及组] 守望者的逃离
    [NOIP2007普及组]守望者的逃离题目背景NOIP2007普及组T3题目描述恶魔猎手尤迪安野心勃勃,他背叛了暗夜精灵,率领深藏在海底的娜迦族企图叛变。守望者在与尤迪安的交锋中遭遇了围杀,被困在一个荒芜的大岛上。为了杀死守望者,尤迪安开始对这个荒岛施咒,这座岛很快就会沉下去。到那时,岛......