zoukankan      html  css  js  c++  java
  • 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?" ":"
    ");
            }
        }
        return 0;
    }
    
  • 相关阅读:
    程序员:不要自称为码农
    SpringBoot对静态资源配置
    LeetCode 572. Subtree of Another Tree(子树)
    LeetCode 437. Path Sum III(统计路径和等于sum的路径数量)
    LeetCode 112. Path Sum(判断路径和是否等于一个数)
    LeetCode 617. Merge Two Binary Trees(归并两棵二叉树)
    LeetCode 226. Invert Binary Tree(翻转二叉树)
    Failure to transfer org.apache.maven.plugins:maven-resources-plugin:pom:2.6 的解决办法
    linux-查询某软件的安装的目录
    WebService概念解释
  • 原文地址:https://www.cnblogs.com/sciorz/p/9115767.html
Copyright © 2011-2022 走看看