1. 程式人生 > >The Blocks Problem

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; }