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