JZOJ.5281【NOIP2017模拟8.15】钦点
很明显这是一道模拟题,朴素算法O(nmq)看似过得去,实际上字符串的操作是很慢的,同样对字符串赋值10w次比对数组元素赋值10w次要慢3倍以上。
实际上我们可以像剪布一样,剪出边缘然后整体粘贴过去。
我们就可以建立链表,每次只用修改矩形的边缘点的关系即可。复杂度O((n + m)q)。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<algorithm> 6 #include<cmath> 7 #include<ctime> 8 #define N 1005 9 using namespace std; 10 struct data{ 11 int nx,ny,sx,sy,ex,ey,wx,wy; 12 }pos[N][N]; 13 string qwq[N][N],qaq; 14 int n,m,q,x1,x2,y3,y2,l,r,tmp1,tmp2,a,b,x,y,c,d,qxq,qyq,qvq; 15 void ee(int &a,int &b,int c){ //右移 16 int w=a,e=b; 17 while(c--){ 18 a=pos[w][e].ex; 19 b=pos[w][e].ey; 20 w=a; 21 e=b; 22 } 23 } 24 void ww(int &a,int &b,int c){ //左移 25 int w=a,e=b; 26 while(c--){ 27 a=pos[w][e].wx; 28 b=pos[w][e].wy; 29 w=a; 30 e=b; 31 } 32 } 33 void nn(int &a,int &b,int c){ //上移 34 int w=a,e=b; 35 while(c--){ 36 a=pos[w][e].nx; 37 b=pos[w][e].ny; 38 w=a; 39 e=b; 40 } 41 } 42 void ss(int &a,int &b,int c){ // 下移 43 int w=a,e=b; 44 while(c--){ 45 a=pos[w][e].sx; 46 b=pos[w][e].sy; 47 w=a; 48 e=b; 49 } 50 } 51 int main(){ 52 scanf("%d%d%d",&n,&m,&q); 53 for (int i=1;i<=n;i++) 54 for (int j=1;j<=m;j++){ 55 cin>>qwq[i][j]; 56 pos[i][j].nx=i-1; 57 pos[i][j].ny=j; 58 pos[i][j].sx=i+1; 59 pos[i][j].sy=j; 60 pos[i][j].wx=i; 61 pos[i][j].wy=j-1; 62 pos[i][j].ex=i; 63 pos[i][j].ey=j+1; 64 } 65 for (int i=0;i<=n;i++){ 66 pos[i][0].ex=i; 67 pos[i][0].ey=1; 68 pos[i][n+1].wx=i; 69 pos[i][n+1].wy=n; 70 } 71 for (int i=0;i<=m;i++){ 72 pos[0][i].sx=1; 73 pos[0][i].sy=i; 74 pos[n+1][i].nx=n; 75 pos[n+1][i].ny=i; 76 } 77 while (q--){ 78 scanf("%d%d%d%d%d%d",&x1,&y3,&x2,&y2,&r,&l); 79 qvq=1;tmp1=0;tmp2=0; 80 a=pos[x1][0].ex;b=pos[x1][0].ey;y3--; 81 ee(a,b,y3); 82 c=pos[x2][0].ex;d=pos[x2][0].ey;y2--; 83 ee(c,d,y2); 84 while (true){ 85 if (tmp1==0) { 86 pos[pos[c][d].wx][pos[c][d].wy].ex=a; 87 pos[pos[c][d].wx][pos[c][d].wy].ey=b; 88 pos[pos[a][b].wx][pos[a][b].wy].ex=c; 89 pos[pos[a][b].wx][pos[a][b].wy].ey=d; 90 qxq=pos[a][b].wx; 91 qyq=pos[a][b].wy; 92 pos[a][b].wx=pos[c][d].wx; 93 pos[a][b].wy=pos[c][d].wy; 94 pos[c][d].wx=qxq; 95 pos[c][d].wy=qyq; 96 } 97 if (tmp2==0) { 98 pos[pos[c][d].nx][pos[c][d].ny].sx=a; 99 pos[pos[c][d].nx][pos[c][d].ny].sy=b; 100 pos[pos[a][b].nx][pos[a][b].ny].sx=c; 101 pos[pos[a][b].nx][pos[a][b].ny].sy=d; 102 qxq=pos[a][b].nx; 103 qyq=pos[a][b].ny; 104 pos[a][b].nx=pos[c][d].nx; 105 pos[a][b].ny=pos[c][d].ny; 106 pos[c][d].nx=qxq; 107 pos[c][d].ny=qyq; 108 } 109 if (tmp1==l-1) { 110 pos[pos[c][d].ex][pos[c][d].ey].wx=a; 111 pos[pos[c][d].ex][pos[c][d].ey].wy=b; 112 pos[pos[a][b].ex][pos[a][b].ey].wx=c; 113 pos[pos[a][b].ex][pos[a][b].ey].wy=d; 114 qxq=pos[a][b].ex; 115 qyq=pos[a][b].ey; 116 pos[a][b].ex=pos[c][d].ex; 117 pos[a][b].ey=pos[c][d].ey; 118 pos[c][d].ex=qxq; 119 pos[c][d].ey=qyq; 120 } 121 if (tmp2==r-1) { 122 pos[pos[c][d].sx][pos[c][d].sy].nx=a; 123 pos[pos[c][d].sx][pos[c][d].sy].ny=b; 124 pos[pos[a][b].sx][pos[a][b].sy].nx=c; 125 pos[pos[a][b].sx][pos[a][b].sy].ny=d; 126 qxq=pos[a][b].sx; 127 qyq=pos[a][b].sy; 128 pos[a][b].sx=pos[c][d].sx; 129 pos[a][b].sy=pos[c][d].sy; 130 pos[c][d].sx=qxq; 131 pos[c][d].sy=qyq; 132 } 133 if ((qvq==1)&&(tmp1==l-1)) qvq=2; 134 if ((qvq==2)&&(tmp2==r-1)) qvq=3; 135 if ((qvq==3)&&(tmp1==0)) qvq=4; 136 if (qvq==1) {tmp1++;ee(a,b,1);ee(c,d,1);} 137 if (qvq==2) {tmp2++;ss(a,b,1);ss(c,d,1);} 138 if (qvq==3) {tmp1--;ww(a,b,1);ww(c,d,1);} 139 if (qvq==4) {tmp2--;nn(a,b,1);nn(c,d,1);} 140 if ((qvq==4)&&(tmp2==0)) break; 141 } 142 } 143 a=0;b=0; 144 a=pos[0][1].sx; 145 b=pos[0][1].sy; 146 x=a,y=b; 147 c=a,d=b; 148 while (true){ 149 cout<<qwq[x][y]<<' '; 150 if ((pos[x][y].sx==n+1)&&(pos[x][y].sy==m)&&(pos[x][y].ex==n)&&(pos[x][y].ey==m+1)) break; 151 if (pos[x][y].ey==m+1) { 152 c=pos[a][b].sx; 153 d=pos[a][b].sy; 154 a=c; 155 b=d; 156 x=c; 157 y=d; 158 cout<<endl; 159 continue; 160 } 161 x=pos[c][d].ex; 162 y=pos[c][d].ey; 163 c=x; 164 d=y; 165 } 166 return 0; 167 }
这里在整个矩形的外围还围了一圈,这一圈是不会变动的,方便我们定位要修改的矩形的左上角在哪。
实际上只要每个点记录右边和下面的关系就好了。
码力很重要