CodeForces 706E Working routine

十字链表。

开一个十字链表,矩阵中每一格作为一个节点,记录五个量:

$s[i].L$:$i$节点左边的节点编号

$s[i].R$:$i$节点右边的节点编号

$s[i].U$:$i$节点上面的节点编号

$s[i].D$:$i$节点下面的节点编号

$s[i].V$:$i$节点存储的值

每次操作,只要把四个边上的那些边拆掉,重新连上新的边就可以了。时间复杂度:$O(qn)$。

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<iostream>
using namespace std;
typedef long long LL;
const double pi=acos(-1.0),eps=1e-8;
void File()
{
    freopen("D:\\in.txt","r",stdin);
    freopen("D:\\out.txt","w",stdout);
}

const int maxn=1010;
int n,m,k,sz;
struct X { int u,d,l,r,v; }s[maxn*maxn];
int a[maxn*maxn],id[maxn][maxn];

int main()
{
    scanf("%d%d%d",&n,&m,&k);

    for(int i=0;i<=n;i++) id[i][0]=sz++; for(int j=1;j<=m;j++) id[0][j]=sz++;
    for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) id[i][j]=sz++;
    for(int i=1;i<=n;i++) id[i][m+1]=sz++; for(int j=1;j<=m;j++) id[n+1][j]=sz++;

    for(int i=0;i<=n+1;i++)
    {
        for(int j=0;j<=m+1;j++)
        {
            s[id[i][j]].l=-1; s[id[i][j]].r=-1; s[id[i][j]].u=-1; s[id[i][j]].d=-1;

            if(j-1>=0) s[id[i][j]].l=id[i][j-1]; if(j+1<=m+1) s[id[i][j]].r=id[i][j+1];
            if(i-1>=0) s[id[i][j]].u=id[i-1][j]; if(i+1<=n+1) s[id[i][j]].d=id[i+1][j];
        }
    }

    for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&s[id[i][j]].v);

    for(int i=1;i<=k;i++)
    {
        int r1,c1,r2,c2,h,w;
        scanf("%d%d%d%d%d%d",&r1,&c1,&r2,&c2,&h,&w);

        int p1,p2,t1,t2,t3,t4,P1,P2;

        p1=r1,p2=r2;
        for(int j=1;j<=c1;j++) p1=s[p1].r; for(int j=1;j<=c2;j++) p2=s[p2].r;

        P1=p1,P2=p2;
        for(int j=1;j<=w-1;j++) P1=s[P1].r; for(int j=1;j<=w-1;j++) P2=s[P2].r;
        for(int j=1;j<=h-1;j++) P1=s[P1].d; for(int j=1;j<=h-1;j++) P2=s[P2].d;

        t1=p1,t2=p2; t3=s[p1].l; t4=s[p2].l;
        for(int j=1;j<=h;j++) swap(s[t1].l,s[t2].l), t1=s[t1].d, t2=s[t2].d;
        for(int j=1;j<=h;j++) swap(s[t3].r,s[t4].r), t3=s[t3].d, t4=s[t4].d;

        t1=p1,t2=p2; t3=s[p1].u; t4=s[p2].u;
        for(int j=1;j<=w;j++) swap(s[t1].u,s[t2].u), t1=s[t1].r, t2=s[t2].r;
        for(int j=1;j<=w;j++) swap(s[t3].d,s[t4].d), t3=s[t3].r, t4=s[t4].r;

        p1=P1,p2=P2;

        t1=p1,t2=p2; t3=s[p1].d; t4=s[p2].d;
        for(int j=1;j<=w;j++) swap(s[t1].d,s[t2].d), t1=s[t1].l, t2=s[t2].l;
        for(int j=1;j<=w;j++) swap(s[t3].u,s[t4].u), t3=s[t3].l, t4=s[t4].l;

        t1=p1,t2=p2; t3=s[p1].r; t4=s[p2].r;
        for(int j=1;j<=h;j++) swap(s[t1].r,s[t2].r), t1=s[t1].u, t2=s[t2].u;
        for(int j=1;j<=h;j++) swap(s[t3].l,s[t4].l), t3=s[t3].u, t4=s[t4].u;

    }
    for(int i=1;i<=n;i++)
    {
        int p=i;
        for(int j=1;j<=m;j++)
            p=s[p].r, printf("%d ",s[p].v);
        printf("\n");
    }

    return 0;
}
时间: 2024-10-15 14:31:48

CodeForces 706E Working routine的相关文章

【链表】【模拟】Codeforces 706E Working routine

题目链接: http://codeforces.com/problemset/problem/706/E 题目大意: 给一个N*M的矩阵,Q个操作,每次把两个同样大小的子矩阵交换,子矩阵左上角坐标分别为(a,b)和(c,d),高度h,宽度w. (2 ≤ n, m ≤ 1000, 1 ≤ q ≤ 10 000) 题目思路: [链表][模拟] 这一看如果直接模拟的话时间复杂度是N*M*Q,肯定T了. 把矩阵看成链表,链表的方向有上下左右四种,其实每次交换两个子矩阵只改变的外围一圈的链表值,而内部的链

Codeforces Round #196 (Div. 2) B. Routine Problem

screen 尺寸为a:b video 尺寸为 c:d 如果a == c 则 面积比为 cd/ab=ad/cb (ad < cb) 如果b == d 则 面积比为 cd/ab=cb/ad  (cb < ad) 如果不相等时 如果a/b > c/d,则ad/bd > cb/db 则(ad > cb) screen尺寸可为 ad:bd, video的尺寸可为 cb:db 面积比为:cb*db/ad*bd = cb/ad (ad > cb) 如果a/b < c/d,则a

十字链表 Codeforces Round #367 E Working routine

1 // 十字链表 Codeforces Round #367 E Working routine 2 // 题意:给你一个矩阵,q次询问,每次交换两个子矩阵,问最后的矩阵 3 // 思路:暴力肯定不行.我们可以每个元素建立十字链表,记录右边和下边的元素,和每个元素的下标(从0开始),每次询问只需要交换四条边的指向即可. 4 // 本题要建立(n+1)*(m+1)的矩阵 5 6 #include <bits/stdc++.h> 7 using namespace std; 8 #define

Codeforces gym 100685 F. Flood bfs

F. FloodTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100685/problem/F Description We all know that King Triton doesn't like us and therefore shipwrecks, hurricanes and tsunami do happen. But being bored with the same routine

【codeforces 718E】E. Matvey&#39;s Birthday

题目大意&链接: http://codeforces.com/problemset/problem/718/E 给一个长为n(n<=100 000)的只包含‘a’~‘h’8个字符的字符串s.两个位置i,j(i!=j)存在一条边,当且仅当|i-j|==1或s[i]==s[j].求这个无向图的直径,以及直径数量. 题解:  命题1:任意位置之间距离不会大于15. 证明:对于任意两个位置i,j之间,其所经过每种字符不会超过2个(因为相同字符会连边),所以i,j经过节点至多为16,也就意味着边数至多

Codeforces 124A - The number of positions

题目链接:http://codeforces.com/problemset/problem/124/A Petr stands in line of n people, but he doesn't know exactly which position he occupies. He can say that there are no less than a people standing in front of him and no more than b people standing b

Codeforces 841D Leha and another game about graph - 差分

Leha plays a computer game, where is on each level is given a connected graph with n vertices and m edges. Graph can contain multiple edges, but can not contain self loops. Each vertex has an integer di, which can be equal to 0, 1 or  - 1. To pass th

Codeforces Round #286 (Div. 1) A. Mr. Kitayuta, the Treasure Hunter DP

链接: http://codeforces.com/problemset/problem/506/A 题意: 给出30000个岛,有n个宝石分布在上面,第一步到d位置,每次走的距离与上一步的差距不大于1,问走完一路最多捡到多少块宝石. 题解: 容易想到DP,dp[i][j]表示到达 i 处,现在步长为 j 时最多收集到的财富,转移也不难,cnt[i]表示 i 处的财富. dp[i+step-1] = max(dp[i+step-1],dp[i][j]+cnt[i+step+1]) dp[i+st

Codeforces 772A Voltage Keepsake - 二分答案

You have n devices that you want to use simultaneously. The i-th device uses ai units of power per second. This usage is continuous. That is, in λ seconds, the device will use λ·ai units of power. The i-th device currently has bi units of power store