Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <cstdio>
- #include <cstdlib>
- #include <algorithm>
- #include <cmath>
- #include <vector>
- #include <set>
- #include <map>
- #include <unordered_set>
- #include <unordered_map>
- #include <queue>
- #include <ctime>
- #include <cassert>
- #include <complex>
- #include <string>
- #include <cstring>
- #include <chrono>
- #include <random>
- #include <bitset>
- using namespace std;
- #ifdef LOCAL
- #define eprintf(...) fprintf(stderr, __VA_ARGS__);fflush(stderr);
- #else
- #define eprintf(...) 42
- #endif
- using ll = long long;
- using ld = long double;
- using uint = unsigned int;
- using ull = unsigned long long;
- template<typename T>
- using pair2 = pair<T, T>;
- using pii = pair<int, int>;
- using pli = pair<ll, int>;
- using pll = pair<ll, ll>;
- mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
- ll myRand(ll B) {
- return (ull)rng() % B;
- }
- #define pb push_back
- #define mp make_pair
- #define all(x) (x).begin(),(x).end()
- #define fi first
- #define se second
- clock_t startTime;
- double getCurrentTime() {
- return (double)(clock() - startTime) / CLOCKS_PER_SEC;
- }
- struct Move {
- int id;
- int x, y, z;
- Move() : id(-1), x(), y(), z() {}
- Move(int _id, int _x, int _y, int _z) : id(_id), x(_x), y(_y), z(_z) {}
- };
- const int N = 9;
- const int M = 40404;
- const int TT = 100100;
- int dist[M][N];
- Move par[M][N];
- int tr[M][N][N][N];
- int CU, CD, CX;
- int n;
- int f[N];
- vector<int> fromId[M];
- vector<pii> Q[TT];
- vector<int> ANS;
- const int UP = 1;
- const int DOWN = 2;
- const int SHIFT_PRESS = 3;
- const int SHIFT_RELEASE = 4;
- const int CTRL_X = 5;
- const int CTRL_V = 6;
- string COMM[] = {"Up", "Down", "Shift-Press", "Shift-Release", "Ctrl+X", "Ctrl+V"};
- void addMove(Move MV) {
- vector<int> cur;
- if (MV.z == -1) {
- if (MV.y == -1)
- cur.push_back(UP);
- else
- cur.push_back(DOWN);
- } else {
- int st = MV.x;
- if (MV.y < 0) st += MV.y;
- cur.push_back(SHIFT_PRESS);
- for (int i = 0; i < MV.y; i++)
- cur.push_back(DOWN);
- for (int i = 0; i > MV.y; i--)
- cur.push_back(UP);
- cur.push_back(SHIFT_RELEASE);
- cur.push_back(CTRL_X);
- for (int i = st; i < MV.z; i++)
- cur.push_back(DOWN);
- for (int i = st; i > MV.z; i--)
- cur.push_back(UP);
- cur.push_back(CTRL_V);
- }
- reverse(all(cur));
- for (int x : cur) ANS.push_back(x);
- }
- void printCommand(int x) {
- cout << COMM[x - 1] << endl;
- }
- int toId(const vector<int> &p) {
- int res = 0;
- for (int i = 0; i < n; i++) {
- for (int j = i + 1; j < n; j++)
- if (p[j] < p[i])
- res += f[n - 1 - i];
- }
- return res;
- }
- void relaxDist(int id, int pos, int newDist, Move P) {
- if (dist[id][pos] <= newDist) return;
- dist[id][pos] = newDist;
- par[id][pos] = P;
- Q[newDist].push_back(mp(id, pos));
- }
- int main()
- {
- startTime = clock();
- // freopen("input.txt", "r", stdin);
- // freopen("output.txt", "w", stdout);
- f[0] = 1;
- for (int i = 1; i < N; i++)
- f[i] = f[i - 1] * i;
- scanf("%d", &n);
- scanf("%d%d", &CU, &CD);
- for (int i = 0; i < 4; i++) {
- int x;
- scanf("%d", &x);
- CX += x;
- }
- fromId[0] = vector<int>(n);
- for (int i = 0; i < n; i++)
- fromId[0][i] = i;
- for (int t = 1; t < f[n]; t++) {
- fromId[t] = fromId[t - 1];
- next_permutation(all(fromId[t]));
- }
- for (int id = 0; id < f[n]; id++) {
- vector<int> p = fromId[id];
- for (int i = 0; i < n; i++)
- for (int len = 1; i + len <= n; len++) {
- vector<int> q;
- q.reserve(n - len);
- for (int j = 0; j < n; j++) {
- if (i <= j && j < i + len) continue;
- q.push_back(p[j]);
- }
- for (int t = 0; t + len <= n; t++) {
- vector<int> w;
- w.reserve(n);
- for (int j = 0; j < t; j++)
- w.push_back(q[j]);
- for (int j = i; j < i + len; j++)
- w.push_back(p[j]);
- for (int j = t; j < n - len; j++)
- w.push_back(q[j]);
- tr[id][i][len][t] = toId(w);
- }
- }
- }
- eprintf("precalc = %.5lf\n", getCurrentTime());
- int S, T;
- vector<int> p(n);
- for (int i = 0; i < n; i++) {
- scanf("%d", &p[i]);
- p[i]--;
- }
- S = toId(p);
- for (int i = 0; i < n; i++) {
- scanf("%d", &p[i]);
- p[i]--;
- }
- T = toId(p);
- for (int id = 0; id < f[n]; id++)
- for (int i = 0; i <= n; i++)
- dist[id][i] = TT;
- relaxDist(S, 0, 0, Move());
- for (int D = 0; D < TT; D++) {
- //eprintf("D = %d\n", D);
- while(!Q[D].empty()) {
- pii V = Q[D].back();
- Q[D].pop_back();
- int id = V.first, pos = V.second;
- if (dist[id][pos] != D) continue;
- if (pos > 0) {
- relaxDist(id, pos - 1, D + CU, Move(id, pos, -1, -1));
- }
- if (pos + 1 <= n) {
- relaxDist(id, pos + 1, D + CD, Move(id, pos, 1, -1));
- }
- for (int len = 1; pos + len <= n; len++)
- for (int npos = 0; npos + len <= n; npos++) {
- int nid = tr[id][pos][len][npos];
- if (id == nid) continue;
- relaxDist(nid, npos + len,
- D + CX + CD * len + max(0, npos - pos) * CD + max(0, pos - npos) * CU,
- Move(id, pos, len, npos));
- }
- for (int len = 1; len <= pos; len++)
- for (int npos = 0; npos + len <= n; npos++) {
- int nid = tr[id][pos - len][len][npos];
- if (id == nid) continue;
- relaxDist(nid, npos + len,
- D + CX + CU * len + max(0, npos - (pos - len)) * CD + max(0, (pos - len) - npos) * CU,
- Move(id, pos, -len, npos));
- }
- }
- }
- int pos = 0;
- for (int i = 0; i <= n; i++)
- if (dist[T][pos] > dist[T][i])
- pos = i;
- printf("%d ", dist[T][pos]);
- //return 0;
- while(dist[T][pos] > 0) {
- Move MV = par[T][pos];
- addMove(MV);
- T = MV.id;
- pos = MV.x;
- }
- reverse(all(ANS));
- printf("%d\n", (int)ANS.size());
- for (int x : ANS) {
- printCommand(x);
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement