Codeforces Round #367 (Div. 2)E. Working routine

链接:http://codeforces.com/contest/706/problem/E

题意:给定一个n*m的矩阵,给定q次剪切交换,每次给出a,b,c,d,h,w表示将左上角为(a,b)和左上角为(c,d)的高h宽w的矩阵交换,保证两个矩形不重叠没有公共边。

分析:对每个格子建一个十字链表,每次剪切的时候我们只需要将周围的那些链表交换即可。O(q*(n+m))

代码:

#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<bitset>
#include<math.h>
#include<vector>
#include<string>
#include<stdio.h>
#include<cstring>
#include<iostream>
#include<algorithm>
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
const int N=1010;
const int mod=998244353;
const int MOD1=1000000007;
const int MOD2=1000000009;
const double EPS=0.00000001;
typedef long long ll;
const ll MOD=1000000007;
const int INF=1000000010;
const ll MAX=1ll<<55;
const double eps=1e-5;
const double inf=~0u>>1;
const double pi=acos(-1.0);
typedef double db;
typedef unsigned int uint;
typedef unsigned long long ull;
struct node {
    int x,y;
    node(){}
    node(int x,int y):x(x),y(y){}
}L[N][N],R[N][N],U[N][N],D[N][N];
int g[N][N];
int main()
{
    int i,j,n,m,q;
    int a,b,c,d,h,w;
    node now1,swp1,now2,swp2;
    node top_left1,top_left2;
    scanf("%d%d%d", &n, &m, &q);
    for (i=1;i<=n;i++)
        for (j=1;j<=m;j++) scanf("%d", &g[i][j]);
    for (i=0;i<=n+1;i++)
        for (j=0;j<=m+1;j++) {
            L[i][j]=node(i,j-1);R[i][j]=node(i,j+1);
            U[i][j]=node(i-1,j);D[i][j]=node(i+1,j);
        }
    while (q--) {
        scanf("%d%d%d%d%d%d", &a, &b, &c, &d, &h, &w);
        top_left1=node(a,0);top_left2=node(c,0);
        for (i=1;i<=b;i++) top_left1=R[top_left1.x][top_left1.y];
        for (i=1;i<=d;i++) top_left2=R[top_left2.x][top_left2.y];
        now1=top_left1;now2=top_left2;
        for (i=1;i<=w;i++) {
            swp1=U[now1.x][now1.y];swp2=U[now2.x][now2.y];
            U[now1.x][now1.y]=swp2;U[now2.x][now2.y]=swp1;
            D[swp1.x][swp1.y]=now2;D[swp2.x][swp2.y]=now1;
            if (i!=w) now1=R[now1.x][now1.y],now2=R[now2.x][now2.y];
        }
        for (i=1;i<=h;i++) {
            swp1=R[now1.x][now1.y];swp2=R[now2.x][now2.y];
            R[now1.x][now1.y]=swp2;R[now2.x][now2.y]=swp1;
            L[swp1.x][swp1.y]=now2;L[swp2.x][swp2.y]=now1;
            if (i!=h) now1=D[now1.x][now1.y],now2=D[now2.x][now2.y];
        }
        for (i=1;i<=w;i++) {
            swp1=D[now1.x][now1.y];swp2=D[now2.x][now2.y];
            D[now1.x][now1.y]=swp2;D[now2.x][now2.y]=swp1;
            U[swp1.x][swp1.y]=now2;U[swp2.x][swp2.y]=now1;
            if (i!=w) now1=L[now1.x][now1.y],now2=L[now2.x][now2.y];
        }
        for (i=1;i<=h;i++) {
            swp1=L[now1.x][now1.y];swp2=L[now2.x][now2.y];
            L[now1.x][now1.y]=swp2;L[now2.x][now2.y]=swp1;
            R[swp1.x][swp1.y]=now2;R[swp2.x][swp2.y]=now1;
            if (i!=h) now1=U[now1.x][now1.y],now2=U[now2.x][now2.y];
        }
    }
    for (i=1;i<=n;i++) {
        now1=node(i,0);
        for (j=1;j<=m;j++) {
            now1=R[now1.x][now1.y];
            printf("%d ", g[now1.x][now1.y]);
        }
        printf("\n");
    }
    return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值