【CodeForces706E】Working routine(二维链表)

BUPT2017 wintertraining(15) #6B

题意

q次操作,每次把两个给定子矩阵交换,求最后的矩阵。(2 ≤ n, m ≤ 1000, 1 ≤ q ≤ 10 000)

题解

用R[i]和D[i]记录编号i的右方和下方的编号。交换两个子矩阵只要修改四周的R和D即可。为了方便查找给定位置的编号,每行每列都需要头结点,也就是给一个编号。

代码

#include <cstdio>
#include <iostream>
#define N 1005*1005
using namespace std;
int n,m,q;
int v[N],D[N],R[N];

int no(int x,int y){
	return x*(m+1)+y;
}
int main() {
	scanf("%d%d%d",&n,&m,&q);
	for(int i=0;i<=n;i++)
	for(int j=0;j<=m;j++)
		D[no(i,j)]=no(i+1,j),R[no(i,j)]=no(i,j+1);
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++)
		scanf("%d",&v[no(i,j)]);
	while(q--){
		int x,y,xx,yy,h,w;
		scanf("%d%d%d%d%d%d",&x,&y,&xx,&yy,&h,&w);
		int u=y-1,v=yy-1,uu=y-1+w,vv=yy-1+w;
		for(int i=1;i<x;i++)u=D[u],uu=D[uu];//u(x-1,y-1);uu(x-1,y-1+h)
		for(int i=1;i<xx;i++)v=D[v],vv=D[vv];//v(xx-1,yy-1);vv(xx-1,yy-1+h)
		for(int j=u,k=v,i=0;i<w;i++){//交换上面一行的D
			j=R[j],k=R[k];
			swap(D[j],D[k]);
		}
		for(int i=0;i<h;i++){//分别交换左右两列的R
			u=D[u],v=D[v];
			swap(R[u],R[v]);
			uu=D[uu],vv=D[vv];
			swap(R[uu],R[vv]);
		}
		for(int i=0;i<w;i++){//交换最下行的D
			u=R[u],v=R[v];
			swap(D[u],D[v]);
		}
	}
	
	for(int i=1,x;i<=n;i++){
		x=R[no(i,0)];
		for(int j=1;j<=m;j++)
			printf("%d ",v[x]),x=R[x];
		puts("");
	}
	return 0;
}
原文地址:https://www.cnblogs.com/flipped/p/6608177.html