给定一个n*m的矩阵( 2<=n,m<=1000)和q次操作(1<=q<=10000)
对于每个任务,被要求交换这个矩阵中的两个子矩阵。
每个任务,会获得六个正整数x1,y1,x2,y2,h,w,x1,y1 代表了第一个矩阵 左上角的行列位置(即在第x1 行第y1 列);x2,y2 代表了第二个矩阵左上角的行列位置,h,w 代表了这两个矩阵的高和宽(即行数和列数)。最后,输出n行m个数,表示完成q次交换后的矩阵
如果暴力做的话复杂度应该为O(nmp),而n*m*q=,显然不行
通过分析可以发现,在一个矩阵中,除了边框(第一行,第一列,最后一行,最后一列)以外的位置,上下左右的元素是不发生变化的,所以可以通过链表维护,只改变边框对元素进行维护
有些人(比如我)可能会觉得只横着链,好像又可以满足条件又可以是代码变得更简短,写完后样例过了结果一交全wa。这里我们来分析一下原因
这是一份横向链表的代码,主程序没法保证没法确保(x1,y1)在若干次交换后还是b[x1][y1],所以需要查找(x1,y1)时应该从头通过链表寻找
//代码有一点小长(误抄哦)
#include
using namespace std;
int n,m,q,h,w,xl,yl,x2,y2,a[1005][1005];
struct node{ int x,y; };
node x,y,s,ss,u,uu,t,tt,r,rr,b[1005][1005][5];
int read()
{
int s=0; char c=getchar(); bool f=0;
for(;!isdigit(c);c=getchar()) f^=!(c^45);
for(;isdigit(c);c=getchar()) s=(s<<1)+(s<<3)+(c^48);
if(f) s=-s; return s;
}
int main()
{
scanf("%d%d%d",&n,&m,&q);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++) a[i][j]=read();
for(int i=0;i<=n+1;i++)
for(int j=0;j<=m+1;j++)
{
b[i][j][0]=(node){i-1,j};//up
b[i][j][1]=(node){i+1,j};//down
b[i][j][2]=(node){i,j-1};//left
b[i][j][3]=(node){i,j+1};//right
}
while(q--)
{
scanf("%d%d%d%d%d%d",&xl,&yl,&x2,&y2,&h,&w);
x=y={0,0};
//更新左上角
for(int i=1;i<=xl;i++) x=b[x.x][x.y][1];
for(int i=1;i<=yl;i++) x=b[x.x][x.y][3];
for(int i=1;i<=x2;i++) y=b[y.x][y.y][1];
for(int i=1;i<=y2;i++) y=b[y.x][y.y][3];
r=s=x,t=u=y;
//更新左侧
for(int i=1;i<=h;i++)
{
rr=b[r.x][r.y][2],tt=b[t.x][t.y][2];
b[rr.x][rr.y][3]=t,b[tt.x][tt.y][3]=r;
b[r.x][r.y][2]=tt,b[t.x][t.y][2]=rr;
r=b[r.x][r.y][1]; t=b[t.x][t.y][1];
}
r=b[r.x][r.y][0]; t=b[t.x][t.y][0];
//更新右侧
for(int i=1;i<=w;i++)
{
rr=b[r.x][r.y][1],tt=b[t.x][t.y][1];
b[rr.x][rr.y][0]=t,b[tt.x][tt.y][0]=r;
b[r.x][r.y][1]=tt,b[t.x][t.y][1]=rr;
r=b[r.x][r.y][3]; t=b[t.x][t.y][3];
}
//更新上侧
for(int i=1;i<=w;i++)
{
ss=b[s.x][s.y][0],uu=b[u.x][u.y][0];
b[ss.x][ss.y][1]=u,b[uu.x][uu.y][1]=s;
b[s.x][s.y][0]=uu,b[u.x][u.y][0]=ss;
s=b[s.x][s.y][3],u=b[u.x][u.y][3];
}
//更新右侧
s=b[s.x][s.y][2],u=b[u.x][u.y][2];
for(int i=1;i<=h;i++)
{
ss=b[s.x][s.y][3],uu=b[u.x][u.y][3];
b[ss.x][ss.y][2]=u,b[uu.x][uu.y][2]=s;
b[s.x][s.y][3]=uu,b[u.x][u.y][3]=ss;
s=b[s.x][s.y][1],u=b[u.x][u.y][1];
}
}
x={0,0}; x=b[x.x][x.y][3];
for(int i=1;i<=n;i++)
{
x=b[x.x][x.y][1],y=x;
for(int j=1;j<=m;j++)
{
cout<