description
题意就是一开始给出一个n*m的矩阵,然后有Q操作,每次把这个矩阵中的两个子矩阵的所有值交换,这两个子矩阵不能相交。输出最后矩阵的形态。(2 ≤ n, m ≤ 1000, 1 ≤ q ≤ 10 000)
Solution
一开始本来想用splay来处理的,对于每一行的处理,直接弄一下就好,所以复杂度为O(NQ
log
N),由于时限为2.5s,所以勉强卡过。
但后来才发现有更简单的解法。。。
对于一次操作,会对一个位置的上下左右产生影响,你会发现,这些位置刚好分布在要交换矩阵的四条边上和它的上下两行前后两列。但记录一个位置的左边和这个位置的左边记录他的右边是等价的,所以我们省去两个,只记录一个位置的右边和下边分别是什么,那么对于一次交换,设第一个矩形左上角坐标为(x,y),第二个矩形左上角为(xx,yy),矩形长为L,宽为W,我们只要更新第x-1行、x+L-1行和xx-1行、xx+L-1行的下边的坐标和第y-1列、yy+W-1行和yy-1列、yy+W-1行的右边的值即可。值得注意的是,我们一开始并不知道现在(x-1,y-1)坐标上和(xx-1,yy-1)坐标上的是原图中什么坐标,所以我们先从(0,0)走起,往下走x-1行,往左走y-1列,就可得知现在(x-1,y-1)坐标上原图中什么坐标,(xx-1,yy-1)同理。
最后,只需从(0,0)把原图遍历一遍即可得到现在的矩形。
Code
#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=1005;
struct code{
int dx,dy,rx,ry;
}f[maxn][maxn];
int n,m,i,t,j,k,l,x,y,xx,yy,h,w,c[maxn][maxn],d[maxn][maxn],bz[maxn][maxn],num,t1,k1,a,b,a1,b1;
int p,q,p1,q1,q2;
void dg(int x,int y,int x1,int y1){
if (bz[x][y]) return;
bz[x][y]=1;
d[x1][y1]=c[x][y];
dg(f[x][y].dx,f[x][y].dy,x1+1,y1);
dg(f[x][y].rx,f[x][y].ry,x1,y1+1);
}
int main(){
// freopen("data.in","r",stdin);
scanf("%d%d%d",&n,&m,&q2);
for (i=1;i<=n;i++)
for (j=1;j<=m;j++)
scanf("%d",&c[i][j]);
for (i=0;i<=n;i++)
for (j=0;j<=m;j++)
f[i][j].dx=i+1,f[i][j].dy=j;
for (i=0;i<=n;i++)
for (j=0;j<=m;j++)
f[i][j].rx=i,f[i][j].ry=j+1;
for (j=1;j<=q2;j++){
scanf("%d%d%d%d%d%d",&x,&y,&xx,&yy,&h,&w);
a=0;b=0;
for (i=1;i<x;i++)
t=a,a=f[a][b].dx,b=f[t][b].dy;
for (i=1;i<y;i++)
t=a,a=f[a][b].rx,b=f[t][b].ry;
a1=0,b1=0;
for (i=1;i<xx;i++)
t=a1,a1=f[a1][b1].dx,b1=f[t][b1].dy;
for (i=1;i<yy;i++)
t=a1,a1=f[a1][b1].rx,b1=f[t][b1].ry;
t=a,k=b;
t1=a1;k1=b1;
for (i=1;i<=w;i++){
l=t,t=f[t][k].rx,k=f[l][k].ry;
l=t1,t1=f[t1][k1].rx,k1=f[l][k1].ry;
if (i==w){
p=t,q=k,p1=t1,q1=k1;
continue;
}
swap(f[t][k].dx,f[t1][k1].dx);
swap(f[t][k].dy,f[t1][k1].dy);
}
for (i=1;i<=h;i++){
l=t,t=f[t][k].dx,k=f[l][k].dy;
l=t1,t1=f[t1][k1].dx,k1=f[l][k1].dy;
swap(f[t][k].rx,f[t1][k1].rx);
swap(f[t][k].ry,f[t1][k1].ry);
}
swap(f[p][q].dx,f[p1][q1].dx);
swap(f[p][q].dy,f[p1][q1].dy);
t=a,k=b;
t1=a1;k1=b1;
for (i=1;i<=h;i++){
l=t,t=f[t][k].dx,k=f[l][k].dy;
l=t1,t1=f[t1][k1].dx,k1=f[l][k1].dy;
if (i==h){
p=t,q=k,p1=t1,q1=k1;
continue;
}
swap(f[t][k].rx,f[t1][k1].rx);
swap(f[t][k].ry,f[t1][k1].ry);
}
for (i=1;i<=w;i++){
l=t,t=f[t][k].rx,k=f[l][k].ry;
l=t1,t1=f[t1][k1].rx,k1=f[l][k1].ry;
swap(f[t][k].dx,f[t1][k1].dx);
swap(f[t][k].dy,f[t1][k1].dy);
}
swap(f[p][q].rx,f[p1][q1].rx);
swap(f[p][q].ry,f[p1][q1].ry);
}
dg(0,0,0,0);
for (i=1;i<=n;i++){
for (j=1;j<=m;j++)
printf("%d ",d[i][j]);
printf("\n");
}
}