洛谷 P2790 ccj与zrz之积木问题

题目背景

ccj和zrz无聊到了玩起了搭积木...(本题选自uva101,翻译来自《算法竞赛入门经典2》)

题目描述

从左到右有n个木块,编号从0到n-1,要求模拟以下4种操作(下面的a和B都是木块编号,归为表示比如1号木块归到1号位去)。

move a onto b 把a和b上方的木块全部归位,然后把a摞在b上面。

move a over b 把a上方的全部归位,然后把a放在b所在木块堆的顶部。

pile a onto b 把b上方的木块全部归位,然后把a及上面的木块整体摞在b上面

pile a over b 把a及上面的木块整体摞在b所在木块堆的顶部。

遇到quit停止。a和b在同一堆的指令时非法指令,应当忽略。

最后输出每个位置的木块列表,按照从底部到顶部的顺序排列。

输入输出格式

输入格式:

 

第一行:n。

接下来若干行:每行一个指令(语法不会错),遇到quit停止。

 

输出格式:

 

n行,第i行输出一个i和冒号,然后一个空格,输出,它位置上的所有积木。

 

输入输出样例

输入样例#1: 复制
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
输出样例#1: 复制
0: 0
1: 1 9 2 4
2:
3: 3
4:
5: 5 8 7 6
6:
7:
8:
9:

说明

0 < n < 25。

 思路:模拟

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n,a,b;
int id[30];
char s[3][5];
struct nond{
    int num[30],top;
}v[30];
void work1(){
    int pos=id[a];
    for(int i=v[pos].top;i>=1;i--)
        if(v[pos].num[v[pos].top]!=a){
            v[v[pos].num[v[pos].top]].top++;
            id[v[id[a]].num[v[id[a]].top]]=v[id[a]].num[v[id[a]].top];
            v[v[pos].num[v[pos].top]].num[v[v[pos].num[v[pos].top]].top]=v[pos].num[v[pos].top];
            v[id[a]].top--;
        }
        else{
            v[id[a]].top--;v[id[b]].top++;
            v[id[b]].num[v[id[b]].top]=a;
            id[a]=id[b];
            break;
        }
}
void work2(){
    for(int i=v[id[a]].top;i>=1;i--)
        if(v[id[a]].num[v[id[a]].top]!=a){
            v[v[id[a]].num[v[id[a]].top]].top++;
            id[v[id[a]].num[v[id[a]].top]]=v[id[a]].num[v[id[a]].top];
            v[v[id[a]].num[v[id[a]].top]].num[v[v[id[a]].num[v[id[a]].top]].top]=v[id[a]].num[v[id[a]].top];
            v[id[a]].top--;
        }
    for(int i=v[id[b]].top;i>=1;i--)
        if(v[id[b]].num[v[id[b]].top]!=b){
            v[v[id[b]].num[v[id[b]].top]].top++;
            id[v[id[b]].num[v[id[b]].top]]=v[id[b]].num[v[id[b]].top];
            v[v[id[b]].num[v[id[b]].top]].num[v[v[id[b]].num[v[id[b]].top]].top]=v[id[b]].num[v[id[b]].top];
            v[id[b]].top--;
        }
    v[id[a]].top--;v[id[b]].top++;
    v[id[b]].num[v[id[b]].top]=a;
    id[a]=id[b];
}
void work3(){
    for(int i=v[id[b]].top;i>=1;i--)
        if(v[id[b]].num[v[id[b]].top]!=b){
            v[v[id[b]].num[v[id[b]].top]].top++;
            id[v[id[b]].num[v[id[b]].top]]=v[id[b]].num[v[id[b]].top];
            v[v[id[b]].num[v[id[b]].top]].num[v[v[id[b]].num[v[id[b]].top]].top]=v[id[b]].num[v[id[b]].top];
            v[id[b]].top--;
        }
    int pos=id[a];
    for(int i=v[pos].top;i>=1;i--)
        if(v[pos].num[i]==a){
            for(int j=i;j<=v[pos].top;j++){
                v[id[b]].top++;
                v[id[b]].num[v[id[b]].top]=v[pos].num[j];
                id[v[pos].num[j]]=id[b];
            }
            v[pos].top-=i;
            break;
        }
}
void work4(){
    int pos=id[a];
    for(int i=v[pos].top;i>=1;i--)
        if(v[pos].num[i]==a){
            for(int j=i;j<=v[pos].top;j++){
                v[id[b]].top++;
                v[id[b]].num[v[id[b]].top]=v[pos].num[j];
                id[v[pos].num[j]]=id[b];
            }
            v[pos].top-=i;
            break;
        }
}
int main(){
    scanf("%d",&n);
    for(int i=0;i<n;i++)    v[i].num[1]=i,v[i].top=1,id[i]=i;
    for(int i=1;i<=n;i++){
        cin>>s[1];
        if(s[1][0]=='m'){
            scanf("%d",&a);
            scanf("%s %d",s[2],&b);
            if(id[a]==id[b])    continue;
            if(s[2][1]=='v')    work1();
            else work2();
        }
        else if(s[1][0]=='p'){
            scanf("%d",&a);
            scanf("%s %d",s[2],&b);
            if(id[a]==id[b])    continue;
            if(s[2][1]=='n')    work3();
            else work4();
        }
        else    break;
    }
    for(int i=0;i<n;i++){
        cout<<i<<": ";
        for(int j=1;j<=v[i].top;j++)
            cout<<v[i].num[j]<<" ";
        cout<<endl;
    }
}
调不出来的40分gg

思路:用vector维护。

#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n,a,b;
int h1,q1,h2,q2;
char p[10],q[10];
vector<int>s[32];
void find(){
    for(int i=0;i<n;i++)
    for(int o=0;o<s[i].size();o++){
        if(s[i][o]==a){ h1=i;q1=o; }
        if(s[i][o]==b){ h2=i;q2=o; }
    }
}
void moveonto(){
    for(int i=q1+1;i<s[h1].size();i++)
           s[s[h1][i]].push_back(s[h1][i]);
    for(int i=q2+1;i<s[h2].size();i++)
        s[s[h2][i]].push_back(s[h2][i]);
    s[h1].resize(q1);
    s[h2].resize(q2+1);
    s[h2].push_back(a);
}
void moveover(){
    for(int i=q1+1;i<s[h1].size();i++)
        s[s[h1][i]].push_back(s[h1][i]);
    s[h1].resize(q1);
    s[h2].push_back(a);
}
void pileonto(){
    for(int i=q2+1;i<s[h2].size();i++)
        s[s[h2][i]].push_back(s[h2][i]);
    s[h2].resize(q2+1);
    for(int i=q1;i<s[h1].size();i++)
        s[h2].push_back(s[h1][i]);
    s[h1].resize(q1);
}
void pileover(){
    for(int i=q1;i<s[h1].size();i++)
        s[h2].push_back(s[h1][i]);
    s[h1].resize(q1);
}
int main(){
    scanf("%d",&n);
    for(int i=0;i<n;i++)    s[i].push_back(i);
    while(1){
        scanf("%s",p);
        if(strcmp(p,"quit")==0)    break;
        scanf("%d%s%d",&a,q,&b);
        find();
        if(h1==h2)    continue;
        if(strcmp(p,"move")==0&&strcmp(q,"onto")==0)    moveonto();
        if(strcmp(p,"move")==0&&strcmp(q,"over")==0)    moveover();
        if(strcmp(p,"pile")==0&&strcmp(q,"onto")==0)    pileonto();
        if(strcmp(p,"pile")==0&&strcmp(q,"over")==0)    pileover();
    }
    for(int i=0;i<n;i++){
        printf("%d:",i);
        for(int o=0;o<s[i].size();o++)
            printf(" %d",s[i][o]);
        printf("\n");
    }
}

 

posted @ 2017-11-23 20:20  一蓑烟雨任生平  阅读(292)  评论(0编辑  收藏  举报