codeforces 706E
我随手一交就是一个AC
题意,一个n*m的矩阵,n,m<=1000,每次交换两个没有公共部分的子矩阵(可以有公共角),进行q<10000次操作,输出最后的矩阵。
题解:对我来说太神啦,居然是用链表,每个点维护它下面和右边的点是什么,建一个(n+1)*(m+1)的矩阵,矩阵的右下n*m部分是原矩阵,然后,每次交换矩阵就交换它们周围一圈的节点的指向即可。
我的代码有点不影响正确性的小bug,会在sawp的过程中swap两个点(因为先交换了向下的指针,在走向下,p和g会进行一两次交换),但p和g是等价的,它们交换不会影响什么,也不会使程序变慢。可以通过增加两个变量解决。虽然谈不上错,但程序员还是知道自己的程序在干什么会比较好,这题不WA,说不定下一题就错了。
1 #include<bits/stdc++.h> 2 #define maxn 1005 3 using namespace std; 4 int n,m,q,cnt,a,b,c,d,h,w,p1,p2,y,g,u,v,s1,s2; 5 struct node{ 6 int rn,bn,val; 7 }p[1100005]; 8 int x[maxn][maxn]; 9 inline void swap(int &a,int &b){a+=b;b=a-b;a-=b;} 10 int main(){ 11 scanf("%d%d%d",&n,&m,&q); 12 for(int i=0;i<=n;i++) 13 for(int j=0;j<=m;j++){ 14 x[i][j]=++cnt; 15 } 16 cnt=0; 17 for(int i=0;i<=n;i++) 18 for(int j=0;j<=m;j++){ 19 cnt++; 20 p[cnt].rn=x[i][j+1]; 21 p[cnt].bn=x[i+1][j]; 22 } 23 for(int i=p[1].bn;i;i=p[i].bn) 24 for(int j=p[i].rn;j;j=p[j].rn){ 25 scanf("%d",&p[j].val); 26 } 27 for(int i=1;i<=q;i++){ 28 scanf("%d%d%d%d%d%d",&b,&a,&d,&c,&h,&w);p1=p2=1; 29 for(int i=1;i<a;i++) p1=p[p1].rn; 30 for(int i=1;i<b;i++) p1=p[p1].bn; 31 for(int i=1;i<c;i++) p2=p[p2].rn; 32 for(int i=1;i<d;i++) p2=p[p2].bn; 33 y=p[p1].rn;g=p[p2].rn;u=p[p1].bn;v=p[p2].bn; 34 for(int i=1;i<w;i++){ 35 swap(p[y].bn,p[g].bn); 36 y=p[y].rn;g=p[g].rn; 37 } 38 swap(p[y].bn,p[g].bn); 39 y=p[y].bn;g=p[g].bn; 40 for(int i=1;i<h;i++){ 41 swap(p[u].rn,p[v].rn); 42 swap(p[y].rn,p[g].rn); 43 u=p[u].bn;v=p[v].bn;y=p[y].bn;g=p[g].bn; 44 } 45 swap(p[u].rn,p[v].rn); 46 u=p[u].rn;v=p[v].rn; 47 swap(p[y].rn,p[g].rn); 48 for(int i=1;i<=w;i++){ 49 swap(p[u].bn,p[v].bn); 50 u=p[u].rn;v=p[v].rn; 51 } 52 } 53 for(int i=p[1].bn;i;i=p[i].bn){ 54 for(int j=p[i].rn;j;j=p[j].rn){ 55 printf("%d ",p[j].val); 56 }printf("\n"); 57 } 58 return 0; 59 }