The Blocks Problem

The Blocks Problem

题目链接:The Blocks Problem

题目概述:给你n个方块,有四种操作:

  1. move a onto b,把a和b上面的方块都放回原来位置,然后把a放到b上面;
  2. move a over b,把a上面的放回原处,然后把a放在b所在的方块堆的上面;
  3. pile a onto b,把b上面的放回原来位置,然后把a和a上面的方块整体放到b上面;
  4. pile a over b,把a和a上面的方块整体放到b所在堆的上面。

Input:

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
quit

Output:

0: 0
1: 1 9 2 4
2:
3: 3
4:
5: 5 8 7 6
6:
7:
8:
9:

解题思路:这里我用了类的方式,过于麻烦。可不必采用这种方式。接下来说下代码思路:
主要数据结构是short place[25]list<short> n_list[25] place用来记录当前木块在那一列上,值为最底部木块的值。n_list 记录没一列上放置的木块。move 两个操作比较简单,pile两个操作需要考虑 a 在一列的中间的情况。详细情况看代码。


最终代码:

#include <iostream>
#include <list>
#include <string>
#include <algorithm>
using namespace std;

class Block{
    public:
        Block(int n):length(n){
            for(int i=0;i < n ;i++){
                    place[i]=i;
                    n_list[i].push_back(i);
            }
        }
        void moveOnto(int a,int b){
            if(this->isCounfict(a,b)){
                this->reSet(a);
                this->reSet(b);
                n_list[place[b]].push_back(a);
                n_list[place[a]].pop_back();
                place[a]=place[b];
            }

        }
        void moveOver(int a,int b){
            if(this->isCounfict(a,b)){
                this->reSet(a);
                n_list[place[b]].push_back(a);
                n_list[place[a]].pop_back();
                place[a]=place[b];
            }
        }
        void pileOnto(int a,int b){
            if(this->isCounfict(a,b)){
                this->reSet(b);
                int flag = false;
                int couser= place[a];
                for (list<short>::iterator i = n_list[couser].begin(); i != n_list[couser].end(); ++i){
                    if(*i==a){
                        flag = true;
                    }
                    if(flag){
                        n_list[place[b]].push_back(*i);
                        place[*i]=place[b];
                    }

                }
                while(n_list[couser].back()!=a){
                    n_list[couser].pop_back();
                }
                n_list[couser].pop_back();
            }
        }
        void pileOver(int a,int b){

            if(this->isCounfict(a,b)){
                int flag = false;
                int couser= place[a];
                for (list<short>::iterator i= n_list[couser].begin(); i != n_list[couser].end(); ++i){
                    if(*i==a){
                        flag = true;
                    }
                    if(flag){
                        n_list[place[b]].push_back(*i);
                        place[*i]=place[b];
                    }
                }


                while(n_list[couser].back()!=a){
                    n_list[couser].pop_back();
                }
                n_list[couser].pop_back();
            }
        }
        void printArr(){

            for(int j = 0; j < length; j++)
            {
                cout <<j<<":";
                for (list<short>::iterator i = n_list[j].begin(); i != n_list[j].end(); ++i){
                    cout<<" "<<*i;
                }
                cout<<endl;
            }
        }

    private:
        int length;
        short place[25];
        list<short> n_list[25];
        bool isCounfict(int a,int b){
            if(a==b || place[a]==place[b])
                return false;
            return true;
        }
        void reSet(int n){
            int couser= place[n];
            int current=n_list[couser].back();
            while(current!=n){
                place[current] = current;
                n_list[current].push_back(current);
                n_list[couser].pop_back();
                current=n_list[couser].back();
            }
        }
};

int main()
{
   int n=0;
   int a=0,b=0;
   string commands;
   cin>>n;
   Block *block= new Block(n);
   while(true){
        cin >> commands;
        if(commands=="move"){
            cin >> a;
            cin >> commands;
            if(commands =="onto"){
                cin>>b;
                block->moveOnto(a,b);
            }
            if(commands == "over"){
                cin>>b;
                block->moveOver(a,b);
            }
        }
        if(commands== "pile"){
            cin >> a;
            cin >> commands;
            if(commands =="onto"){
                cin>>b;
                block->pileOnto(a,b);
            }
            if(commands == "over"){
                cin>>b;
                block->pileOver(a,b);
            }
        }
        if(commands== "quit"){
            block->printArr();
            break;
        }
   }
    delete block;

   return 0;

}
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

一只放纵的死魂灵

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

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

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

打赏作者

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

抵扣说明:

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

余额充值