RT,貌似发在灌水区里才有人看的样子(
只有40pts,在本地造的数据,会出现“temp.exe已停止运行”的状况,此时栈顶保存的元素 top[y]
为负数,但是本人并没有找到哪里出了问题。
代码的思路是:利用分治,把球的颜色小于等于mid的看做1,其他的看做0,进行解决。
代码中有少量极丑的英文注释,为了防止我以后看不懂打的(
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
using namespace std;
int a[53][402],top[402],cnt,ans[820005][3];
void move(int x,int y) { //move x -> y
top[y]++;
a[y][top[y]]=a[x][top[x]];
top[x]--; //move the ball
cnt++;
ans[cnt][0]=x,ans[cnt][1]=y; //get the ans
}
int n,m;
bool flag[402];
void divi(int l,int r) {
if(l==r) return;
memset(flag,0,sizeof(flag));
int mid=(l+r)>>1;
for(int I=1;I<=mid;I++) {
for(int J=mid+1;J<=r;J++) {
int i=I,j=J;
if(flag[i] || flag[j]) continue;
int sum=0;
for(int k=1;k<=m;k++) {
sum+=(a[i][k] <= mid);
sum+=(a[j][k] <= mid);
} // get the sum of the val of ther ball which is <= mid , recognize them to 1 , if sum >= m , make m balls which number is 1 to i , other make to j
if(sum >= m) {
sum=0;
for(int k=1;k<=m;k++) sum+=(a[i][k] <= mid);
for(int k=1;k<=sum;k++) move(j,n+1);
while(top[i]) {
a[i][top[i]] <= mid ? move(i,j) : move(i,n+1);
}
for(int k=1;k<=sum;k++) move(j,i);
for(int k=1;k<=m-sum;k++) move(n+1,i);
for(int k=1;k<=m-sum;k++) move(j,n+1);
for(int k=1;k<=m-sum;k++) move(i,j);
while(top[n+1]) {
if(top[i]==m || a[n+1][top[n+1]] > mid) move(n+1,j);
else move(n+1,i);
}
flag[i]=1;
} else {
swap(i,j);
sum=0;
for(int k=1;k<=m;k++) sum+=(a[i][k] > mid);
for(int k=1;k<=sum;k++) move(j,n+1);
while(top[i]) {
a[i][top[i]] > mid ? move(i,j) : move(i,n+1);
}
for(int k=1;k<=sum;k++) move(j,i);
for(int k=1;k<=m-sum;k++) move(n+1,i);
for(int k=1;k<=m-sum;k++) move(j,n+1);
for(int k=1;k<=m-sum;k++) move(i,j);
while(top[n+1]) {
if(top[i]==m || a[n+1][top[n+1]] <= mid) move(n+1,j);
else move(n+1,i);
}
flag[i]=1;
}
}
}
divi(l,mid);
divi(mid+1,r);
}
int main() {
#ifdef LOCAL
freopen("in.in","r",stdin);
freopen("out.out","w",stdout);
#endif
//========================================
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&a[i][j]),top[i]++;
divi(1,n);
printf("%d\n",cnt);
for(int i=1;i<=cnt;i++)
printf("%d %d\n",ans[i][0],ans[i][1]);
//========================================
return 0;
}