• NOIP模拟 table


    题目大意:

    给一个n*m的矩阵,每次交换两个大小相同的不重叠的子矩阵,输出最后的矩阵

    题目分析:

    这题向我们展示了出神入化的链表是如何炼成的。思想都懂,实现是真的需要技术,%%%
    用一副链表来表示该矩阵,每个节点记录他的右节点和下节点,这样在交换两个矩阵时,只需要暴力交换两个矩阵的边框,并更新边框外面的相关信息,边框内的信息不用更改(相对位置不变),最后从左上角输出即可。

    code

    #include<bits/stdc++.h>
    using namespace std;
    
    namespace IO{
        inline int read(){
            int i = 0, f = 1; char ch = getchar();
            for(; (ch < '0' || ch > '9') && ch != '-'; ch = getchar());
            if(ch == '-') f = -1, ch = getchar();
            for(; ch >= '0' && ch <= '9'; ch = getchar()) i = (i << 3) + (i << 1) + (ch - '0');
            return i * f;
        }
        inline void wr(int x){
            if(x < 0) putchar('-'), x = -x;
            if(x > 9) wr(x / 10);
            putchar(x % 10 + '0');
        }
    }using namespace IO;
    
    const int N = 1005, M = 1005003;
    int n, m, q, v[M], num[N][N], tot;
    int lst[M][2];
    
    inline int get(int x, int y){
        int now = num[0][0];
        for(int i = 1; i <= x; i++) now = lst[now][1];
        for(int i = 1; i <= y; i++) now = lst[now][0];
        return now;
    }
    
    int main(){
        freopen("h.in", "r", stdin);
        n = read(), m = read(), q = read();
        for(register int i = 1; i <= n; i++)
            for(register int j = 1; j <= m; j++)
                v[num[i][j] = ++tot] = read();
        // for(int i = 1; i <= tot; i++) cout<<v[i]<<endl;
        for(register int i = 0; i <= m + 1; i++) num[0][i] = ++tot, num[n + 1][i] = ++tot;
        for(register int i = 1; i <= n; i++) num[i][0] = ++tot, num[i][m + 1] = ++tot;
        for(register int i = 0; i <= n; i++)
            for(register int j = 0; j <= m; j++){
                lst[num[i][j]][0] = num[i][j + 1];
                lst[num[i][j]][1] = num[i + 1][j];
            }
        // for(int i = 1; i <= n; i++)
        //     for(int j = 1; j <= m; j++)
        //         cout<<i<<" @"<<j<<" "<<lst[num[i][j]][0]<<" "<<lst[num[i][j]][1]<<endl;
        for(; q; q--){
            int a, b, c, d, h, w;
            a = read(), b = read(), c = read(), d = read(), h = read(), w = read();
            int pos1 = get(a - 1, b - 1), pos2 = get(c - 1, d - 1);
            // cout<<pos1<<" "<<pos2<<endl;
            register int t1, t2, ww, hh;
    
            for(t1 = pos1, t2 = pos2, ww = 1; ww <= w; ww++)
                swap(lst[t1 = lst[t1][0]][1], lst[t2 = lst[t2][0]][1]);
            for(hh = 1; hh <= h; hh++)
                swap(lst[t1 = lst[t1][1]][0], lst[t2 = lst[t2][1]][0]);
            for(t1 = pos1, t2 = pos2, hh = 1; hh <= h; hh++)
                swap(lst[t1 = lst[t1][1]][0], lst[t2 = lst[t2][1]][0]);
            for(ww = 1; ww <= w; ww++)
                swap(lst[t1 = lst[t1][0]][1], lst[t2 = lst[t2][0]][1]);
        }
    
        int now = num[0][0];
        for(register int i = 1; i <= n; i++){
            for(register int j = 1, t = now = lst[now][1]; j <= m; j++)
                cout<<v[t = lst[t][0]]<<" ";
            cout<<endl;
        }
        return 0;
    }
    
  • 相关阅读:
    C# 从Excel 批量导入数据库
    SQL、Linq和Lambda表达式 的关系
    layer 中的 layer.alert layer.msg layer.confirm
    jquery 关于使用 append 追加 元素后 事件无法触发
    eBay 开发流程
    WCF学习笔记(2)——使用IIS承载WCF服务
    WCF学习笔记(1)——Hello WCF
    [老老实实学WCF] 第十篇 消息通信模式(下) 双工
    [老老实实学WCF] 第九篇 消息通信模式(上) 请求应答与单向
    [老老实实学WCF] 第八篇 实例化
  • 原文地址:https://www.cnblogs.com/CzYoL/p/7701062.html
Copyright © 2020-2023  润新知