例题5-2 UVA101 The Blocks Problem

难度: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;
}
上一篇:zhx的趣味题


下一篇:[CF1503C]Travelling Salesman Problem