有人知道怎么写吗
2026-04-09 15:27:34
发布于:江苏
7阅读
0回复
0点赞
以下为我的代码
#include <cassert>
#include <cstdio>
#include <iostream>
#define mkp make_pair
#define fi first
#define se second
using namespace std;
const int _ = 50 + 7;
const int __ = 400 + 7;
const int ___ = 1e6 + 7;
int n, m, p[_][__], top[_], numAct, num[_], sta[_], rec, lim;
bool flag = 0;
pair<int, int> act[___];
void Mark(int x, int y) {
for (int i = 1; i <= n; ++i) num[i] = sta[i] = 0;
for (int i = 1; i <= m; ++i) ++num[p[x][i]], ++num[p[y][i]];
int cnt = 0;
for (int i = 1; i <= n; ++i) {
if (cnt + num[i] <= m) cnt += num[i], sta[i] = -1;
else {
sta[i] = 0, lim = m - cnt;
for (int j = i + 1; j <= n; ++j) sta[j] = 1;
break;
}
}
}
bool Check(int x) {
if (sta[x] != 0) return sta[x] == -1;
if (rec < lim) { ++rec; return 1; };
return 0;
}
void Move(int x, int y) {
act[++numAct] = mkp(x, y);
p[y][++top[y]] = p[x][top[x]]; --top[x];
}
void Oran(int x, int y, int z = n + 1) {
Mark(x, y);
int cnt = 0; rec = 0;
for (int i = 1; i <= m; ++i)
if (Check(p[x][i])) ++cnt;
for (int i = 1; i <= cnt; ++i) Move(y, z);
rec = 0;
for (int i = m; i >= 1; --i) Move(x, Check(p[x][i]) ? y : z);
for (int i = 1; i <= cnt; ++i) Move(y, x);
for (int i = 1; i <= m - cnt; ++i) Move(z, x);
for (int i = 1; i <= m - cnt; ++i) Move(y, z);
for (int i = 1; i <= m - cnt; ++i) Move(x, y);
for (int i = m; i >= 1; --i) Move(z, Check(p[z][i]) ? x : y);
}
void Pour(int x, int y) {
int tmp = top[x];
for (int i = 1; i <= tmp; ++i) Move(x, y);
}
int id[_], pos[_];
void Arr(int l, int r, int z = n + 1) {
for (int i = l; i <= r; ++i)
if (pos[i] != i) {
if (id[i]) {
Pour(i, z);
id[z] = id[i], pos[id[i]] = z, id[i] = 0;
}
Pour(pos[i], i);
id[pos[i]] = 0, z = pos[i], pos[i] = i, id[i] = i;
}
}
int maxn[_];
#define mid ((l + r) >> 1)
void Solve(int l, int r) {
if (l == r) return;
Solve(l, mid); Solve(mid + 1, r);
int t1 = l, t2 = mid + 1;
for (int i = l; i <= r; ++i) {
maxn[i] = 0;
for (int j = 1; j <= m; ++j) maxn[i] = max(maxn[i], p[i][j]);
}
int idx = l - 1;
while (t1 <= mid and t2 <= r) {
while (t1 <= mid and maxn[t1] <= maxn[t2]) { Oran(t1, t2); id[t1] = ++idx, pos[idx] = t1; ++t1; }
if (t1 > mid) break;
while (t2 <= r and maxn[t2] <= maxn[t1]) { Oran(t2, t1); id[t2] = ++idx, pos[idx] = t2; ++t2; }
}
while (t1 <= mid) { id[t1] = ++idx, pos[idx] = t1; ++t1; }
while (t2 <= r) { id[t2] = ++idx, pos[idx] = t2; ++t2; }
Arr(l, r);
}
#undef mid
int main() {
cin >> n >> m;
for (int i = 1; i <= n; ++i) {
top[i] = m;
for (int j = 1; j <= m; ++j) { scanf("%d", &p[i][j]); maxn[i] = max(maxn[i], p[i][j]); }
}
Solve(1, n);
cerr << "num: " << numAct << endl;
cout << numAct << endl;
for (int i = 1; i <= numAct; ++i) printf("%d %d\n", act[i].fi, act[i].se);
return 0;
}
全部评论 2
ddd
1周前 来自 广东
0都是wa
1周前 来自 江苏
0












有帮助,赞一个