P7734
RegisterFault · · 题解
提供一个高级一点的乱搞。
首先发现我们可以利用题目的操作实现这样一个东西:对于
做法很简单。首先把
具体的,假设现在有串 123456__。需要交换 __345612。然后把 5634__12。最后把 563412__。
从前往后构造。我们构造目标序列
由于上述构造中空位的位置不变,因此实现起来非常简单。然后你发现你被卡了。当然这是一个假贪心,很容易被卡掉。
接下来是本文精华。我们随机一个排列
对着这个做法卡个五十次就过了。注意
下面是没写爆搜的代码。
const int N = 2010;
int a[N], tmp[N], t[N], n, m;
char s[N];
vector<pair<int, int>> path;
void Swap(int u, int v) {
swap(a[u], a[v]); swap(a[u + 1], a[v + 1]);
path.push_back({u, m + 1});
path.push_back({v, u});
path.push_back({m + 1, v});
}
void Construct() {
int s0 = 0, s1 = 0;
memcpy(tmp, a, sizeof tmp);
rep(i, 1, m) a[i] == 0 ? s0 ++ : s1 ++ ;
rep(i, 1, s0) t[i] = 0; rep(i, s0 + 1, m) t[i] = 1;
random_shuffle(t + 1, t + m + 1); path.clear();
rep(i, 1, m) if (a[i] != t[i]) {
bool flg = 0;
rep(j, i + 2, m - 1) if (a[j] == t[i]) {
flg = 1; Swap(i, j); break;
} if (!flg) { memcpy(a, tmp, sizeof a); return; }
}
rep(i, 1, s0) t[i] = 0; rep(i, s0 + 1, m) t[i] = 1;
rep(i, 1, m) if (a[i] != t[i]) {
bool flg = 0;
rep(j, i + 2, m - 1) if (a[j] == t[i]) {
flg = 1; Swap(i, j); break;
} if (!flg) { memcpy(a, tmp, sizeof a); return; }
}
printf("%d\n", (int)path.size());
for (auto i : path) printf("%d %d\n", i.first, i.second);
exit(0);
}
int main() {
srand(998244353);
scanf("%s", s + 1); n = strlen(s + 1);
m = n - 2; rep(i, 1, m) a[i] = s[i] - '0';
rep(i, 1, 100) Construct(); puts("-1");
}