题解:CF2092D Mishkin Energizer
不难发现形如 LIT 的串是万能的。证明如下:
- 可以多生成一个
L 变为 LILT。
- 可以多生成一个
T 变为 LTIT。
- 想要多生成一个
I,先选择上面两个的其中一个操作,然后同理即可。
进一步地,只要存在相邻两个字母不同,就可以花费一个操作变为万能串。每一步最多操作两次即可向着目标前进,故总次数不会超过 $2n$。
由于还需要记录路径,当 LIT 变为 ILT 后,需要注意万能串最左侧的位置会增加 $1$。直接用 while 配套着 swap 需求的写法最为简洁。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
| #include <bits/stdc++.h> #define init(x) memset (x,0,sizeof (x)) #define ll long long #define ull unsigned long long #define INF 0x3f3f3f3f #define pii pair <int,int> using namespace std; const int MAX = 105; const int MOD = 1e9 + 7; inline int read (); int t,n,tot,ok,cnt[200];char s[MAX]; vector <int> ans; int main () { tot = 'L' ^ 'I' ^ 'T'; t = read (); while (t--) { n = read ();scanf ("%s",s + 1); ok = cnt['L'] = cnt['I'] = cnt['T'] = 0; ans.clear (); for (int i = 1;i <= n;++i) { if (i > 1 && s[i] != s[i - 1]) ok = 1; ++cnt[s[i]]; } if (!ok) {puts ("-1");continue;} if (cnt['L'] == cnt['I'] && cnt['I'] == cnt['T']) {puts ("0");continue;} for (int i = 2;i <= n;++i) { if (s[i] == s[i - 1]) continue;
int x = s[i - 1],z = s[i],y = tot ^ (x ^ z),p = i - 1; ans.push_back (p);++cnt[y]; while (cnt[x] != cnt[y] || cnt[x] != cnt[z] || cnt[y] != cnt[z]) { if (cnt[x] > cnt[z]) ans.push_back (p),++cnt[z],swap (y,z); else ans.push_back (++p),++cnt[x],swap (x,y); } break; } printf ("%d\n",ans.size ()); for (auto v : ans) printf ("%d\n",v); } return 0; } inline int read () { int s = 0;int f = 1; char ch = getchar (); while ((ch < '0' || ch > '9') && ch != EOF) { if (ch == '-') f = -1; ch = getchar (); } while (ch >= '0' && ch <= '9') { s = s * 10 + ch - '0'; ch = getchar (); } return s * f; }
|