牛客小白月赛21(模拟汉诺塔)

本文详细解析了牛客小白月赛第21场中的一道模拟汉诺塔问题,介绍了游戏规则及编程实现过程,通过代码示例展示了如何模拟汉诺塔游戏,并分享了作者的解题心得。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

牛客小白月赛21(模拟汉诺塔)—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个“-”。
具体输出方式请参看样例进行理解。
样例输入
2
样例输出
在这里插入图片描述.
不是说这道题有多难,就是以后不想在写模拟了,虽然这是一道简单的模拟题,还是菜。代码5分钟debug5小时。
思路:模拟
只为了保存下代码,纪念下这水题。

#pragma GCC optimize(3,"Ofast","inline")  	//G++
#include<bits/stdc++.h>

#define TEST freopen("C:\\Users\\hp\\Desktop\\ACM\\in.txt","r",stdin);
#define mem(a,x) memset(a,x,sizeof(a))
#define debug(x) cout << #x << ": " << x << endl
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);

using namespace std;
typedef long long ll;

const int inf=0x3f3f3f3f;
const ll INF=0x7fffffffffffffff;
const int mod=1e9+7;
const int maxn = 1e6+5;

int n,num[10],N;
int LINE;
char s[300005][305];
stack<int>a,b,c;
void solve(int line,int _,stack<int>a)
{
    line+=n-a.size();
    while(!a.empty())
    {
        int now=a.top();
        a.pop();
        for(int i=1; i<=now/2; i++)
        {
            s[line][num[_]+i]='*';
            s[line][num[_]-i]='*';
        }
        s[line][num[_]]='*';
        line++;
    }
}
void work(int line)
{
    line+=2;
    solve(line,1,a);
    solve(line,2,b);
    solve(line,3,c);
}
void init(int line)
{
    int cnt=1,__=0;
    while(cnt<=n+2)
    {
        for(int i=1; i<=3*(2*n+1)+4; i++)
        {
            s[line][i]='.';
            if((i-n-1)%(2*n+2)==1&&cnt!=1)
                s[line][i]='|';
        }
        line++,cnt++;
    }
}
void pri()
{
    int cnt=0;
    for(int i=1; i<=(1<<n)*(n+2); i++)
    {
        for(int j=1; j<=3*(2*n+1)+4; j++)
            cout<<s[i][j];
        cout<<"\n";
        cnt++;
        if(cnt==n+2&&i!=(1<<n)*(n+2))
        {
            for(int j=1; j<=3*(2*n+1)+4; j++)
                cout<<"-";
            cout<<"\n";
            cnt=0;
        }
    }
}
void turn(stack<int>&a,stack<int>&b)
{
    int tmp=a.top();
    a.pop();
    b.push(tmp);
    LINE+=N+2;
}
void dfs(int n,stack<int>&a,stack<int>&b,stack<int>&c)
{
    if(n==1)
    {
        turn(a,c);
        work(LINE);
        return ;
    }
    dfs(n-1,a,c,b);
    turn(a,c);
    work(LINE);
    dfs(n-1,b,a,c);
}
int main()
{
    cin>>n;
    N=n,LINE=1;
    int __=0;
    for(int i=1; i<=3*(2*n+1)+4; i++)
        if((i-n-1)%(2*n+2)==1)
            num[++__]=i;
    for(int i=n; i>=1; i--)
        a.push(2*i+1);
    for(int i=1; i<=(1<<n)*(n+2); i+=n+2)
        init(i);
    work(1);
    if(n&1)
    dfs(n,a,c,b);
    else
    dfs(n,a,b,c);
    pri();
}

碎觉 碎觉~~~,又做完一套,欧力给。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值