#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1010;
struct node
{
int right, down;
int v;
}da[maxn*maxn];
int a[maxn][maxn], b[maxn][maxn];
int move(int p, int x, int y)
{
while (x--)
{
p = da[p].down;
}
while (y--)
{
p = da[p].right;
}
return p;
}
void print(int n, int m)
{
int ph = b[0][0];
for(int i=0;i<n;i++)
{
ph = da[ph].down;
int p = da[ph].right;
for (int j = 0; j < m; j++)
{
cout << da[p].v;
p = da[p].right;
if (j == m - 1)
cout << endl;
else
cout << " ";
}
}
}
int main()
{
int n, m, k;
while (scanf("%d%d%d", &n, &m, &k) != EOF)
{
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
scanf("%d", &a[i][j]);
}
}
int t = 0;
for (int i = 0; i <= n; i++)
{
for (int j = 0; j <= m; j++)
{
b[i][j] = t++;
da[b[i][j]].v = a[i][j];
if (i)
da[b[i - 1][j]].down = b[i][j];
if (j)
da[b[i][j - 1]].right = b[i][j];
}
}
while (k--)
{
int x1, y1, x2, y2, h, w;
scanf("%d%d%d%d%d%d", &x1, &y1, &x2, &y2, &h, &w);
//求需要交换的矩阵的左上角的编号
int p1 = move(b[0][0], x1 - 1, y1 - 1);
int p2 = move(b[0][0], x2 - 1, y2 - 1);
int dp1, dp2, rp1, rp2;
//指向矩阵的右边指针交换 左
rp1 = move(p1, 1, 0);
rp2 = move(p2, 1, 0);
for (int i = 0; i < h; i++)
{
swap(da[rp1].right, da[rp2].right);
rp1 = da[rp1].down;
rp2 = da[rp2].down;
}
//指向矩阵的下面指针交换 上
dp1 = move(p1, 0, 1);
dp2 = move(p2, 0, 1);
for (int i = 0; i < w; i++)
{
swap(da[dp1].down, da[dp2].down);
dp1 = da[dp1].right;
dp2 = da[dp2].right;
}
//矩阵指向右边的指针交换 右
rp1 = move(p1, 1, w);
rp2 = move(p2, 1, w);
for (int i = 0; i < h; i++)
{
swap(da[rp1].right, da[rp2].right);
rp1 = da[rp1].down;
rp2 = da[rp2].down;
}
//矩阵指向下面的指针交换 下
dp1 = move(p1, h, 1);
dp2 = move(p2, h, 1);
for (int i = 0; i < w; i++)
{
swap(da[dp1].down, da[dp2].down);
dp1 = da[dp1].right;
dp2 = da[dp2].right;
}
}
print(n, m);
}
return 0;
}
绝了这道题。。。
卡时间卡的真的难受死 前前后后提交了怕有30来次
题意:给出一个n,m的矩阵 再有q个交换 给出两个小矩阵的左上角的坐标 和小矩阵的高和宽 保证两个需要交换位置的小矩阵 高宽一致 且不会有交叉重叠
分析:最直接的暴力莫过于挨个swap 但是这样会超时 所以我们用十字链表 把小矩阵周围的左右上下的指针swap 可以节约大量时间,再有一个是要注意移动的位置。
其实这道题也不是很难,注意细节……只要注意细节……