不难发现形如 LIT 的串是万能的。证明如下:
- 可以多生成一个
L变为LILT。 - 可以多生成一个
T变为LTIT。 - 想要多生成一个
I,先选择上面两个的其中一个操作,然后同理即可。
进一步地,只要存在相邻两个字母不同,就可以花费一个操作变为万能串。每一步最多操作两次即可向着目标前进,故总次数不会超过 2n2n2n。
由于还需要记录路径,当 LIT 变为 ILT 后,需要注意万能串最左侧的位置会增加 111。直接用 while 配套着 swap 需求的写法最为简洁。
#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 ()
{
//freopen (".in","r",stdin);
//freopen (".out","w",stdout);
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;
//由 AB -> ACB 构造万能串
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;
}





