C++解决UVA101 - The Blocks Problem—菜鸡真的想AC(~_~)

101 - The Blocks Problem

终于!!!自己辛辛苦苦想了一天,没有外力的借助下第一次解决了一道模拟题。做完这个题,还是有点总结,总之,一定要把代码写的模块化,让代码看起来有优美的感觉。是“某种动作”最好封装为一个函数。让代码更加简洁。
唔~下面见题解。
[此处是原题](https://onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=37)
题目大意就是说。我是这样理解着去做题的。我把起初定为n个位置,每个位置上有一个该位置对应的木块,比如说1号位置起初就有一个1号木块。定义了以下四种动作。
move a onto b:把a和b上方的木块全部归位,然后把a摞在b上面。
move a over b:把a上方的木块全部归位,然后把a放在b所在木块堆的顶部。
pile a onto b:把b上方的木块全部归位,然后把a及上面的木块整体摞在b上面
pile a over b:把a及上面的木块整体摞在b所在木块堆的顶部。
---------*此处操作中有无效操作,这句很重要,如果要操作的俩个木块在一个位置上,我们就把他视为无效操作,另外归为原位,即放到原来对应的位置,如1号木块对应一号位置*。
**具体细节见代码注释**

另外:最下方有额外的测试数据。
#include <iostream>
#include <cstring>
#include <deque>	//这里我用了一个双向队列打算模拟每个位置n;
using namespace std; 
int block_P[25];  //这个数组的意思是说把每个木块对应的位置保存起来,如block_p[1]保存的是一号木块的位置
void out(int n);
void mo(int a, int b);   //这是我定义的四个命令
void mr(int a, int b);
void po(int a, int b);
void pr(int a, int b);
void cle(int b);     //这个函数的意思就是说检查b号木块上方有没有其他木块,有就移回原位
void adda_to_b(int a, int b);			//此函数为移动函数,将a移动到b号上方
int num(char *a, char *b);	//判断是哪个命令	
int judge(int a, int b);		//判断是否是无效命令
deque<int> block[25];   //这个队列最好设置为全局变量,不然下面处理很麻烦
int main()
{
    int n;
    cin >> n;
    int o = 0;
    int i, j;
    for (i = 0; i < n; i++)
    {
        block[i].push_back(i);  //初始化编号
        block_P[i] = i;
    }
    int first_, end_;
    char first[5], end[5];
    while (cin >> first)
    {
        if(first[0]=='q')
            break;
        cin>> first_ >> end >> end_;
        int judge = num(first, end);
        if (judge == 1)
            mo(first_, end_);
        if (judge == 2)
            mr(first_, end_);
        if (judge == 3)
            po(first_, end_);
        if (judge == 4)
            pr(first_, end_);
        o++;
    }
    out(n);
}
int num(char *a, char *b)
{
    if (a[0] == 'm' && b[3] == 'o')
        return 1;
    if (a[0] == 'm' && b[3] == 'r')
        return 2;
    if (a[0] == 'p' && b[3] == 'o')
        return 3;
    if (a[0] == 'p' && b[3] == 'r')
        return 4;
}
void cle(int b)
{
    int bp = block_P[b];//b号木块的位置
    while (block[bp].back() != b)  //首先判断b号木块所在位置的最上方是不是b,如果不是进行归位
    {
        block[block[bp].back()].push_back(block[bp].back()); 
        block_P[block[bp].back()] = block[bp].back();
        block[bp].pop_back();
    }
}
void adda_to_b(int a, int b)
{
    int bp = block_P[b];
    int ap = block_P[a];
    int o = 0;
    int uu[25];
    while (block[ap].back() != a)//此处操作是比如进行over操作时,我们需要将木块连同上方所有木块移动
    {						 	//这里用数组先保存,最后再按序插入。否则最后的答案可能会顺序颠倒。
        uu[o++] = block[ap].back();
        block_P[block[ap].back()] = bp;
        block[ap].pop_back();
    }
    block[bp].push_back(a);
    block[ap].pop_back();
    block_P[a] = bp;
    if(o!=0){
        for (int i =o-1; i >=0;i--){
            block[bp].push_back(uu[i]);
        }
    }
}
int  judge(int a,int b){
    int bp = block_P[b];
    int ap = block_P[a];
    if (bp == ap)
        return 1;
    return 0;
}
void mo(int a, int b)
{   
    if(judge(a,b)==0)
    {
    cle(b);
    cle(a);
    adda_to_b(a, b);
}}
void mr(int a, int b)
{
    if (judge(a, b)==0)
    {
    cle(a);
    adda_to_b(a, b);
}}
void po(int a, int b)
{
    if (judge(a, b)==0)
   {     
    cle(b);
    adda_to_b(a, b);
}}
void pr(int a, int b)
{
    if (judge(a, b)==0){
       
    adda_to_b(a, b);
}}
void out(int n)
{
    int i;
    for (i = 0; i < n; i++)
    {
        printf("%d:", i);
        while (!block[i].empty())
        {
            printf(" %d", block[i].front());//注意输出格式
            block[i].pop_front();
        }
        printf("\n");
    }
}
}

9
move 4 onto 1
move 8 onto 3
move 7 onto 8
move 8 onto 1
move 2 onto 6
move 1 over 6
move 3 onto 7
move 8 onto 3
pile 2 onto 3
move 4 onto 5
move 6 onto 4
pile 3 onto 4
quit
0: 0
1:
2;
3:
4:
5: 5 4 3 2 1
6: 6
7: 7
8: 8

4
pile 0 over 1
pile 2 over 3
move 1 onto 3
quit
0: 0
1:
2: 2
3: 3 1

10
move 9 onto 1
move 8 over 1
move 7 over 1
move 6 over 1
pile 8 over 6
pile 8 over 5
move 2 over 1
move 4 over 9
pie 4 over 3
pie 1 over 2
pie 0 onto 1
pie 4 over 5
pie 5 onto 9
quit
0:
1: 1 0
2: 2
3: 3
4:
5:
6:
7:
8:
9: 9 5 8 7 6 4

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Code::Blocks 是一个开源的集成开发环境(IDE),主要用于编写和调试C、C++和Fortran程序。如果 Code::Blocks 无法编译C程序,可能存在以下几个可能的原因: 1. 缺少C编译器:Code::Blocks 需要与C编译器一起使用才能编译C程序。确保已经安装了适当的C编译器,例如MinGW(Windows平台上的常见选择)或GCC(Linux平台上的默认编译器)。可以通过在Code::Blocks的设置中配置编译器路径来解决此问题。 2. 配置问题:在Code::Blocks中,需要正确配置编译器才能进行编译。检查Code::Blocks的编译器设置,确保已选择正确的编译器,并且路径设置正确。 3. 代码错误:如果代码中存在语法错误或逻辑错误,编译器将无法将其编译成可执行程序。在编译之前,请确保代码正确且没有错误。 4. 编译器版本不兼容:Code::Blocks可能不兼容特定版本的编译器。尝试使用不同的编译器版本或更新Code::Blocks版本,以解决此类问题。 5. 系统环境问题:某些系统环境可能会导致Code::Blocks无法编译C程序,例如缺少必要的库文件或配置错误。检查系统环境是否满足编译要求,并确保没有其他程序或设置干扰编译过程。 总之,如果Code::Blocks无法编译C程序,需要检查编译器的安装和配置,并确保代码正确且没有错误。如果问题仍然存在,可能需要考虑更换编译器或更新Code::Blocks版本。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小小东西哟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值