复杂度为
O
(
n
log
n
∗
m
)
O(nlog n*m)
O(nlogn∗m),总步数的常数因实现而异。
代码
#include<cstdio>#include<cstring>#include<algorithm>usingnamespace std;#define N 55#define M 410int a[N][M], c[N];struct{int x, y;}to[825000];int ans =0, n, m;voidmv(int x,int y){
a[y][++c[y]]= a[x][c[x]];
a[x][c[x]--]=0;
to[++ans].x = x, to[ans].y = y;}voidsolve(int l,int r){if(l == r)return;int mid =(l + r)/2;int i = l, j = mid +1, k;while(i <= mid && j <= r){int s =0;for(k =1; k <= m; k++) s +=(a[i][k]<= mid);for(k =1; k <= m; k++) s +=(a[j][k]<= mid);int x = i, y = j;if(s > m){int t =0;for(k =1; k <= m; k++) t +=(a[i][k]<= mid);for(k =1; k <= t; k++)mv(j, n +1);for(k = m; k; k--)if(a[i][k]> mid)mv(i, n +1);elsemv(i, j);for(k =1; k <= t; k++)mv(j, i);for(k = t +1; k <= m; k++)mv(n +1, i);for(k = t; k; k--)mv(n +1, j);int t0 =0;for(k =1; k <= m; k++) t0 +=(a[j][k]<= mid);for(k =1; k <= t0; k++)mv(i, n +1);for(k = m; k; k--)if(a[j][k]> mid)mv(j, n +1);elsemv(j, i);for(k =1; k <= t0; k++)mv(i, j);for(k = t0 +1; k <= m; k++)mv(n +1, j);for(k = t0; k; k--)mv(n +1, i);for(k = t +1; k <= m; k++)mv(i, n +1);for(k = t0 +1; k <= m; k++)mv(j, n +1);for(k = t +1; k <= m; k++)mv(j, i);while(c[n +1])mv(n +1, j);
i++;}else{int t =0;for(k =1; k <= m; k++) t +=(a[i][k]> mid);for(k =1; k <= t; k++)mv(j, n +1);for(k = m; k; k--)if(a[i][k]<= mid)mv(i, n +1);elsemv(i, j);for(k =1; k <= t; k++)mv(j, i);for(k = t +1; k <= m; k++)mv(n +1, i);for(k = t; k; k--)mv(n +1, j);int t0 =0;for(k =1; k <= m; k++) t0 +=(a[j][k]> mid);for(k =1; k <= t0; k++)mv(i, n +1);for(k = m; k; k--)if(a[j][k]<= mid)mv(j, n +1);elsemv(j, i);for(k =1; k <= t0; k++)mv(i, j);for(k = t0 +1; k <= m; k++)mv(n +1, j);for(k = t0; k; k--)mv(n +1, i);for(k = t +1; k <= m; k++)mv(i, n +1);for(k = t0 +1; k <= m; k++)mv(j, n +1);for(k = t0 +1; k <= m; k++)mv(i, j);while(c[n +1])mv(n +1, i);
j++;}}solve(l, mid),solve(mid +1, r);}intmain(){int i, j, k, l;scanf("%d%d",&n,&m);for(i =1; i <= n; i++)for(j =1; j <= m; j++)scanf("%d",&a[i][j]);for(i =1; i <= n; i++) c[i]= m;solve(1, n);printf("%d
", ans);for(i =1; i <= ans; i++)printf("%d %d
", to[i].x, to[i].y);return0;}