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;
    }
    
  • 相关阅读:
    jmeter使用教程
    Jmeter的好搭档Badboy的安装与简单使用
    十大编程算法助程序员走上高手之路
    polyfillJS生成promise对象
    js+canvas实现滑动拼图验证码功能
    WebAssembly介绍
    解释器与编译器
    使用axios优雅的发起网络请求
    【javascript】script标签的async异步解析
    sass用法快速入门
  • 原文地址:https://www.cnblogs.com/sciorz/p/9115767.html
Copyright © 2011-2022 走看看