难度:3
这道题是vector的练习。有四个操作,如果一个一个写的话很麻烦,这时要化简,找到操作的共性,然后可以得到,其实只需要两种类型的操作,一个是把一个木块上面的木块全部归位,另一个是把这个木块及其以上的木块照搬到另外一个木块上面,总共就这两种操作,其中第二个操作是每次都要做的,这些都是题目里面的隐含条件,需要自己看出来,除了这两种操作两个函数,还要写一个函数来找到想要操作的木块在第几堆,更详细一点是找到第几堆第几个,刘汝佳是这么写的,我没有这么写,最后需要注意的就是如果两个木块在同一堆,那么是不合法的操作,需要跳过。
#include <bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define all(x) (x).begin(), (x).end()
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pa;
int n;
vi v[30];
int findpos(int x) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < (int) v[i].size(); j++) {
if (v[i][j] == x) return i;
}
}
}
void deal1(int x) {
int pos = findpos(x);
for (int i = (int) v[pos].size() - 1; i >= 0; i--) {
int t = v[pos][i];
if (t == x) break;
v[t].pb(t);
v[pos].pop_back();
}
}
void deal2(int a, int b) {
int pos1 = findpos(a);
int pos2 = findpos(b);
int xx = v[pos2].size();
for (int i = (int) v[pos1].size() - 1; i >= 0; i--) {
int t = v[pos1][i];
v[pos2].pb(t);
v[pos1].pop_back();
if (t == a) break;
}
reverse(v[pos2].begin() + xx, v[pos2].end());
}
void print() {
for (int i = 0; i < n; i++) {
cout << i << ":";
for (int j = 0; j < (int) v[i].size(); j++) {
cout << " " << v[i][j];
}
cout << endl;
}
}
int main() {
cin >> n;
for (int i = 0; i < n; i++) {
v[i].pb(i);
}
string s1, s2;
while (cin >> s1) {
if (s1 == "quit") {
print();
break;
}
int a, b;
cin >> a >> s2 >> b;
if (findpos(a) == findpos(b)) continue;
if (s1 == "move") deal1(a);
if (s2 == "onto") deal1(b);
deal2(a, b);
}
return 0;
}