18-10-13 CodeForces
阿新 • • 發佈:2018-12-15
#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 可以節約大量時間,再有一個是要注意移動的位置。
其實這道題也不是很難,注意細節……只要注意細節……