The Blocks Problem

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xiyaozhe/article/details/81081395

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;

}

猜你喜欢

转载自blog.csdn.net/xiyaozhe/article/details/81081395