2018江苏冬令营5 交换矩阵


题目描述

SR得到了一个n*m的矩阵,矩阵行列从1开始标号,每个格子有不同的权值,Steam为了测试SR的智力,决定给他q个操作,每次操作交换两个大小一样的子矩阵,并在操作完之后输出它。
每个操作由6个正整数\(A_i,B_i,C_i,D_i,H_i,W_i\)组成,分别表示第一个子矩阵的左上角位于哪一行和哪一列、第二个的,以及两个子矩阵的行数和列数。操作保证两个矩阵没有重叠,矩阵的边也不会接壤,即没有任何一条格子的边同时属于两个子矩阵的边界。但是允许角接壤,即
img
SR不想算,请你帮他操作并输出。

输入

第一行三个正整数n,m,q,表示矩阵大小n*m,有q个操作。
接下来n行,每行m个数,表示矩阵每个格子的权值\(v_{i,j}\)
再接下来q行,每行6个正整数,表示一个操作。

输出

共n行,每行m个数,表示操作后的矩阵

样例输入

4 4 2
1 1 2 2
1 1 2 2
3 3 4 4
3 3 4 4
1 1 3 3 2 2
3 1 1 3 2 2

样例输出

4 4 3 3
4 4 3 3
2 2 1 1
2 2 1 1

提示

30%的数据:n,m<=100,q<=500
100%的数据:n,m<=1000,q<=10000,\(|v_{i,j}|<=1e9\),保证修改的子矩阵在大矩阵内。

分析

  • 可以把矩阵用类似于链表的一个东西来表示。每个节点都有一个编号,并在这个节点上记录它下边和右边的节点的编号。
  • 每次修改时,我们只要修改矩阵四周的节点所指向的节点编号。
  • 时间复杂度\(O(n^2+qn\))

代码

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn=1050;
struct node{
    int right,down,val;
}e[maxn*maxn*2];
int h[maxn],t[maxn],tot;
 
int tmp[maxn];
int main(){
    int n,m,q;
    scanf("%d%d%d", &n,&m,&q);
    for(int i = 0; i <= n; ++i) h[i]=++tot;
    for(int j = 1; j <= m; ++j) t[j]=++tot,tmp[j]=tot;
    t[0]=h[0];
    for(int i = 0; i <= n; ++i) e[h[i]].down=h[i+1];
    for(int j = 0; j <= m; ++j) e[t[j]].right=t[j+1];
 
    for(int i = 1; i <= n; ++i){
        int p=h[i];
        for(int j = 1; j <= m; ++j){
            int x;
            scanf("%d", &x);
            ++tot;
            e[tot]=(node){0,0,x};
            e[p].right=tot;
            e[tmp[j]].down=tot;
            p=tmp[j]=tot;
        }
    }
    while(q--){
        int a,b,c,d,H,W;
        scanf("%d%d%d%d%d%d", &a,&b,&c,&d,&H,&W);
        if(H==0||W==0) continue;
        int x1=t[b-1],x2=t[b+W-1],x3=t[d-1],x4=t[d+W-1];
        int v1=h[a-1],v2=h[a+H-1],v3=h[c-1],v4=h[c+H-1];
        for(int i = 1; i <= a; ++i) x1=e[x1].down,x2=e[x2].down;
        for(int i = 1; i <= c; ++i) x3=e[x3].down,x4=e[x4].down;
        for(int j = 1; j <= b; ++j) v1=e[v1].right,v2=e[v2].right;
        for(int j = 1; j <= d; ++j) v3=e[v3].right,v4=e[v4].right;
        for(int i = 1; i <= H; ++i){
            swap(e[x1].right,e[x3].right);
            swap(e[x2].right,e[x4].right);
            x1=e[x1].down;
            x2=e[x2].down;
            x3=e[x3].down;
            x4=e[x4].down;
        }
        for(int i = 1; i <= W; ++i){
            swap(e[v1].down,e[v3].down);
            swap(e[v2].down,e[v4].down);
            v1=e[v1].right;
            v2=e[v2].right;
            v3=e[v3].right;
            v4=e[v4].right;
        }
    }
    for(int i = 1; i <= n; ++i){
        for(int j = e[h[i]].right; j ; j = e[j].right){
            printf("%d%s", e[j].val,e[j].right?" ":"\n");
        }
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/sciorz/p/9115767.html
今日推荐