洛谷 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; } }
思路:用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"); } }
细雨斜风作晓寒。淡烟疏柳媚晴滩。入淮清洛渐漫漫。
雪沫乳花浮午盏,蓼茸蒿笋试春盘。人间有味是清欢。