vector–木块问题
题目描述:
从左到右有n(n<5000)个木块,编号为0~n-1,要求模拟一下4中操作(下面的a和b都是木块的编号)。
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在同一堆的指令非法,应当忽略。
样例输入:
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
样例输出:
0: 0
1: 1 9 2 4
2:
3: 3
4:
5: 5 8 7 6
6:
7:
8:
9:
代码如下:
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
const int maxn = 5000 + 10;
vector<int> a[maxn]; // a[i]保存的是第i堆上的木块
int n; // 木堆的数目
// 寻找编号为x所在的木堆号(p)和具体位置(q)
void find(int x, int& p, int& q) {
for(int i=0; i<n; i++) {
for(int j=0; j<a[i].size(); j++) {
if(a[i][j] == x) {
p = i;
q = j;
return;
}
}
}
}
// 把第p堆木块q上方的木块归位
void clear_above(int p, int q) {
int c;
for(int i=q+1; i<a[p].size(); i++) {
c = a[p][i];
a[c].push_back(c); // 把编号为c的木块归位
}
a[p].resize(q+1); //移除:第p堆木块只保留0~q的元素
}
// 把第pa堆h(包含)上方的木块移动到pb堆木块上面
void shift(int pa, int h, int pb) {
for(int i=h; i<a[pa].size(); i++) {
a[pb].push_back(a[pa][i]);
}
a[pa].resize(h); //移除:第p堆木块只保留0~h-1的元素
}
void print() {
for(int i=0; i<n; i++) {
printf("%d:", i);
for(int j=0; j<a[i].size(); j++) {
printf(" %d", a[i][j]);
}
printf("\n");
}
}
int main() {
scanf("%d", &n);
for(int i=0; i<n; i++) { // 初始化
a[i].push_back(i);
}
char cmd1[5];
char cmd2[5];
int x, y, pa, qa, pb, qb;
while(scanf("%s", cmd1)==1) { // 循环处理命令
if(strcmp(cmd1, "quit")==0) break;
scanf("%d%s%d", &x, cmd2, &y);
find(x, pa, qa);
find(y, pb, qb);
if(pa==pb) continue; // 非法指令,忽略
if(strcmp(cmd1, "move") == 0) { // 归位x上面的木块
clear_above(pa, qa);
}
if(strcmp(cmd2, "onto") ==0) { // 归位y上面的木块
clear_above(pb, qb);
}
shift(pa, qa, pb);
}
print();
return 0;
}
输出结果:
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
0: 0
1: 1 9 2 4
2:
3: 3
4:
5: 5 8 7 6
6:
7:
8:
9:
--------------------------------
Process exited after 19.37 seconds with return value 0
请按任意键继续. . .