牛客小白月赛21有趣的题目

本文介绍了牛客小白月赛21中的几道有趣的算法题目,包括汉诺塔游戏、节目观看时间计算、DDoS攻击策略、斐波那契数列问题、博弈游戏、爱情指数计算以及果冻迷宫问题。通过分析和解决问题,探讨了各种算法的应用和思路。
摘要由CSDN通过智能技术生成

牛客小白月赛21有趣的题目

1.B bits

题目描述

Nancy喜欢做游戏!

汉诺塔是一个神奇的游戏,神奇在哪里呢?

给出3根柱子,最开始时n个盘子按照大小被置于最左的柱子。

如果盘子数为偶数,则需要将她们全部移动到最右侧的柱子上,否则将她们移动到中间的柱子上。

那么,Nancy该怎样移动呢?请你输出汉诺塔游戏的过程叭!

输入描述:

共一行:一个整数n,表示最开始n个盘子(编号为1到n)的放置方法。

数据满足:2≤n≤11。

输出描述:

共2^n组:每组n+2行,每行3×(2n+1)+4个字符,用.表示空白区域,用|表示柱子区域,用*表示盘子。组与组之间请输出3×(2n+1)+4个-。
具体输出方式请参看样例进行理解。

示例1

输入

复制

2

输出

复制

...................
...|.....|.....|...
..***....|.....|...
.*****...|.....|...
-------------------
...................
...|.....|.....|...
...|.....|.....|...
.*****..***....|...
-------------------
...................
...|.....|.....|...
...|.....|.....|...
...|....***..*****.
-------------------
...................
...|.....|.....|...
...|.....|....***..
...|.....|...*****.

题目解释

​ 使用的想法是用二进制来解决汉诺塔的相关问题。详细的解释可以参照B站视频。我们可以发现,假设一共是n个盘子,移动总次数为2n-1次,当n为奇数时,我们可以将盘子移至中间,n为偶数是,我们可以将盘子移至最右边。所以我们就得到了移动的总次数。

#include <cstdio>
#include <stack>
using namespace std;

char map[103][103];
int n;
int w[13];
stack<int> s[3],temp;
//s[3]用来模拟三根柱子,先进后出所以用栈

void input(){
   
    scanf("%d",&n);
}

void output(int n){
   
    int x = n + 2;
    int y = 3 * (2 * n + 1) + 4;
    //先全部置为.
    for(int i = 0;i < x;i++){
   
        for(int j = 0;j < y;j++){
   
            map[i][j] = '.';
        }
    }
    int now = n + 1;
    //在中间添加柱子
    for(int i = 0;i < 3;i++){
   
        for(int j = 1;j < x;j++){
   
            map[j][now] = '|';
            while(s[i].size()){
   
                temp.push(s[i].top());
                s[i].pop();
            }
            //从最后一行开始输出盘子
            int tot = n + 1;
            while(temp.size()){
   
                int x = temp.top();
                for(int l = now - x;l <= now + x;l++){
   
                    map[tot][l] = '*';
                }
                tot--;
                s[i].push(x);
                temp.pop();
            }
        }
        now += 2 * n + 1;
    }
    for(int i = 0;i < x;i++){
   
        for(int j = 0;j < y;j++){
   
            putchar(map[i][j]);
        }
        puts("");
    }
}
//输出分割
void split(){
   
    int y = 3 * (2 * n + 1) + 4;
    for(int i =  0;i < y;i++){
   
        printf("-");
    }
    puts("");
}

void work(){
   
    for(int i = n;i >= 1;i--){
   
        s[0].push(i);//首先所有盘子都在第一根柱子
        w[i] = 0;//w数组用来指示每一个盘子所在的柱子
    }
    output(n);//第一次输出
    int p = (1 << n) - 1;//移动的总次数 
    for(int i = 1;i <= p;i++){
   
        split();
        int num;
        for
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值