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;
}
posted @ 2017-10-20 18:43  CzYoL  阅读(254)  评论(0编辑  收藏  举报