传送门 题意:只有一种操作 shift x 表示 后面x个字符反转在移动到前面来。 问 s字符串能否在6100次操作内变成t。 之前写的每次选择一个字符的步骤为5超过了6100次错了 每次选择一个字符调节位置必须要不超过3次。
ac 代码:
#include <cstdio> #include <string> #include <iostream> #include <map> #include <cstring> #include <queue> #include <algorithm> #include <iterator> using namespace std; typedef long long ll; string s, t; vector<int>q; int n; string pp(int x, string a, int l) { if (x != n) q.push_back(n-x); if (x-l) q.push_back(x-l); q.push_back(l+1); string ks = ""; for (int i = l-1; i >= 0; --i) ks+=a[i]; ks+=a[x]; for (int i = x-1; i >= l; --i) ks+=a[i]; for (int i = n-1; i > x; --i) ks += a[i]; return ks; } void solve() { int x = 0; string k = ""; int l = t.size()/2-1, r = t.size()/2; bool f = 0; while (1) { if (!f) k += t[r++]; else k += t[l--]; if ((l < 0 && r == t.size())) break; f = f^1; } string ks = t; reverse(t.begin(), t.end()); while (s != t && s != ks) { bool f = 0; for (int i = x; i < n; ++i) { if (s[i] == k[x]) { s = pp(i, s, x); x++; f = 1; break; } } if (!f) { puts("-1"); q.clear(); return; } } x = q.size(); printf("%d\n", x+((s==t)?1:0)); for (int i = 0; i < x; ++i) { cout << q[i] << ' '; } if (s == t) printf(" %d\n", n); else puts(""); } bool cmp(string a, string b) { sort(a.begin(), a.end()); sort(b.begin(), b.end()); for (int i = 0; a[i]; ++i) if (a[i] != b[i]) return false; return true; } int main() { while (~scanf("%d", &n)) { cin >> s >> t; if (cmp(s, t)) solve(); else puts("-1"); } }