The Blocks Problem
阿新 • • 發佈:2018-11-01
The Blocks Problem
題目連結:The Blocks Problem
題目概述:給你n個方塊,有四種操作:
- move a onto b,把a和b上面的方塊都放回原來位置,然後把a放到b上面;
- move a over b,把a上面的放回原處,然後把a放在b所在的方塊堆的上面;
- pile a onto b,把b上面的放回原來位置,然後把a和a上面的方塊整體放到b上面;
- 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;
}