本题是一道模拟题,但个人感觉挺有意思的(思路很明确,但是WA了好几发才过),因此来讲一讲思路。
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:
初始时从左到右有 n n n 个木块,编号分别为 0 … n ? 1 0 \ldots n-1 0…n?1,要求实现下列四种操作:
move a onto b
: 把
a
a
a 和
b
b
b 上方的木块归位,然后把
a
a
a 放到
b
b
b 上面。move a over b
: 把
a
a
a 上方的木块归位,然后把
a
a
a 放在
b
b
b 所在木块堆的最上方。pile a onto b
: 把
b
b
b 上方的木块归位,然后把
a
a
a 及以上的木块坨到
b
b
b 上面。pile a over b
: 把
a
a
a 及以上的木块坨到
b
b
b 的上面。一组数据的结束标志为
quit
,如果有非法指令(如 a a a 与 b b b 在同一堆),无需处理。
输出:所有操作输入完毕后,从左到右,从下到上输出每个位置的木块编号。
通过观察上面四种操作,我们会发现,这四种操作可以拆分为三种:
然后我们还会发现,无论哪个操作,最终都会将a放在b上边。
因此,上边的操作就转换为了两类:归位和合并。然后我们实现这两种操作即可。
而这两种操作显然用 v e c t o r vector vector容器比较方便,因此我们尝试用 v e c t o r vector vector来实现。标程里有详细代码+注释,请放心食用。
#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false); cin.tie(nullptr), cout.tie(nullptr);
#define LL long long
#define ULL unsigned long long
#define PII pair<int, int>
#define lowbit(x) (x & -x)
#define Mid ((l + r) >> 1)
#define ALL(x) x.begin(), x.end()
#define endl '\n'
#define fi first
#define se second
const int INF = 0x7fffffff;
const int mod = 1e9 + 7;
const int N = 2e5 + 10;
vector<vector<int>> a(30); //用二维vector,第一维表示原位置,第二维表示当前位置堆的木块
int n, x1, x2;
PII find(int x) { //找到需要进行操作的木块的位置
for(int i = 0; i < n; i ++ )
for(int j = 0; j < a[i].size(); j ++ )
if(a[i][j] == x) return {i, j}; //第i堆的第j个
}
void homing(PII i) { //归位操作
while(a[i.fi].size() - 1 > i.se) {
int t = a[i.fi].back();
a[t].push_back(t); //将其后边的全都归位,本身不动
a[i.fi].pop_back();
}
}
void merge(PII i, PII j) { //合并操作
for(int k = i.se; k < a[i.fi].size(); k ++ ) {
int t = a[i.fi][k];
a[j.fi].push_back(t);
}
a[i.fi].resize(i.se); //将其大小设为i.se,相当于舍弃后面的元素
}
void Solved() {
cin >> n;
string s1, s2;
for(int i = 0; i < n; i ++ ) a[i].push_back(i);//初始化
while(cin >> s1) {
if(s1 == "quit") break;
cin >> x1 >> s2 >> x2;
PII y1 = find(x1), y2 = find(x2); //如果在同一堆的话是没办法进行操作的
if(y1.fi == y2.fi) continue;
if(s2 == "onto") homing(y2); //需要先对b进行操作
if(s1 == "move") homing(y1);
merge(y1, y2);
}
for(int i = 0; i < n; i ++ ) {//输出
cout << i << ":";
for(int j : a[i]) cout << " " << j;
cout << endl;
}
}
signed main(void) {
IOS
int ALL = 1;
// cin >> ALL;
while(ALL -- ) Solved();
// cout << fixed;//强制以小数形式显示
// cout << setprecision(n); //保留n位小数
return 0;
}