CF1500C - Matrix Sorting

CF1500C - Matrix Sorting

题目大意

给定矩阵\(A,B\),现在对于\(A\)进行若干次排序操作

每次选择一列,以这一列为关键字对于所有行进行稳定排序

判断是否能够由\(A\)到\(B\)


分析

可以先通过各种暴力方法求得一个 尽量保持相对顺序 的行匹配

然后考虑对于某一列排序造成怎样的贡献

为了得到最终的序列,不妨考虑最终相邻两行之间的关系

然后对于这一列,根据对应的两个数的关系,所有相邻关系在排序之后

1.可能变得符合

2.保持

3.变得不合法

考虑最后一次操作,那么容易发现其必然不包含3类贡献

而且在最后放了一个这个操作之后,可以断定1类位置符合限制

从而将这些位置从限制中删除

由此不断扩展,最后判断极大的扩展是否合法即可

#include<bits/stdc++.h>
using namespace std;
using ull=uint64_t;
#define rep(i,a,b) for(int i=a,i##end=b;i<=i##end;++i)
enum{N=2000,K=2001};
int n,m,A[N][N],B[N][N],I[N],J[N];
ull HA[N],HB[N];
int F[N][N],D[N],del[N],Q[N],L,R;
int main(){
	scanf("%d%d",&n,&m);
	rep(i,1,n) rep(j,1,m) scanf("%d",A[i]+j),HA[i]=HA[i]*K+A[i][j];
	rep(i,1,n) rep(j,1,m) scanf("%d",B[i]+j),HB[i]=HB[i]*K+B[i][j];
	rep(i,1,n) rep(j,1,n) if(!J[j] && HB[i]==HA[j]) { I[i]=j,J[j]=i; break; }
	rep(i,1,n) if(!I[i]) return puts("-1"),0;
	rep(i,1,m) {
		rep(j,1,n-1) {
			int x=A[I[j]][i],y=A[I[j+1]][i];
			F[i][j]=x<y?2:x==y;
			if(!F[i][j]) D[i]++;
		}
		if(!D[i]) Q[++R]=i;
	}
	while(L<=R) {
		int u=Q[L++];
		rep(i,1,n-1) if(F[u][i]==2 && !del[i]) {
			del[i]=1;
			rep(j,1,m) if(!F[j][i] && --D[j]==0) Q[++R]=j;
		}
	}
	rep(i,1,n-1) if(!del[i] && I[i]>I[i+1]) return puts("-1"),0;
	printf("%d\n",R);
	while(R) printf("%d ",Q[R--]);
}
上一篇:MongoDB基础入门003--使用官方驱动操作mongo,C#


下一篇:基础算法之插入排序(insetion sorting)