PKU 1208 The Blocks Problem(模拟+list应用)

题目大意:原题链接

关键是正确理解题目意思

首先:介绍一下list容器的一些操作:参考链接

list<int> c1;

c1.unique();              去重。

c1.reverse();             反转链表。

c1.insert(pos,num);   在pos位置插入元素num。

c1.insert(pos,n,num);在pos位置插入n个元素num。

c1.assign(n,num);     将n个num拷贝赋值给链表c。

c1.sort();                  将链表排序(默认升序)。

c1.swap(c2);             将c1和c2交换。

c1.remove(num);       删除链表中值为num的元素。

c1.push_back(num);  在末尾位置添加一个元素。

c1.pop_back();          删除最末尾的元素。

c1.push_front(num);  在开始位置添加一个元素。

c1.pop_front();          删除第一个元素。

c1.erase(pos);    删除pos位置的元素。

 

按要求模拟木块移动:有n(0<n<25)块block以及5种操作:

move a onto b:在将a搬到b所在的那堆积木上之前,先把a和b上方的积木放回原來的位置

move a over b:在将a搬到b所在的那堆积木上之前,先把a上方的积木放回原來的位罝

pile a onto b  : 在将a搬到b所在的那堆积木上之前,先将b上方的积木放回原来的位置

pile a over b  : 将包括a本身和a上方的积木一起搬到到b所在的那堆上方(以上三种也都包括a)

quit:结束命令,以上四个操作中,若a和b在同一堆中,则不进行任何操作。

注意:

1.当一个位置的初始箱子移走之后,因为这里没有箱子,其他箱子也不会移到这个位置。

2.数组p[id]=jd表示编号为id的木块放在编号为jd的木块上面 

3.void Move(int x,int y)函数中为了保证移动后保持原来的顺序(包括最下方的木块)而利用一个临时变量

#include<list>
#include<cstdio>
#include<string>
#include<iostream>
using namespace std;
list<int> temp; 
list<int> lis[25];
int p[25];
 
void Recover(int x)
{
    int id=p[x];
    while(lis[id].back()!=x){
        int t=lis[id].back();
        p[t]=t;//细节 
        lis[t].push_back(t);
        lis[id].pop_back(); 
    }
}
void Move(int x,int y)
{
    int id=p[x],jd=p[y];
    while(lis[id].back()!=x){
        temp.push_back(lis[id].back());
        lis[id].pop_back();
    }
    p[x]=jd;//细节 
    lis[jd].push_back(lis[id].back());//正确理解题意保持原来的的顺序 
    lis[id].pop_back();//清理干净 
    while(!temp.empty()){
        lis[jd].push_back(temp.back());
        p[temp.back()]=jd;
        temp.pop_back();
    }
}

int main()
{
    int n,a,b;
    string str1,str2;
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        p[i]=i;
        lis[i].push_back(i);
    }
    while(cin>>str1&&str1!="quit"){
        cin>>a>>str2>>b;
        if(str1=="move"&&str2=="onto"){
            Recover(a);
            Recover(b);
            Move(a,b);
        }
        else if(str1=="move"&&str2=="over"){
            Recover(a);
            Move(a,b);
        }
        else if(str1=="pile"&&str2=="onto"){
            Recover(b);
            Move(a,b);
        }
        else if(str1=="pile"&&str2=="over")
            Move(a,b);
    }
    for(int i=0;i<n;i++){
        printf("%d:",i);
        while(!lis[i].empty()){
            printf(" %d",lis[i].front());
            lis[i].pop_front();
        }
        printf("\n");
    }
}

 

posted @ 2017-03-02 23:26  despair_ghost  阅读(312)  评论(0编辑  收藏  举报