[CSP-S模拟测试]:Drink(模拟)
题目传送门(内部题10)
输入格式
输入第一行三个数$N,M,Q$分别表示棋盘的行数、列数和操作个数。
接下来$N$行每行$M$个数表示一开始棋盘上宝物的价值。
接下来$Q$行每行$3$个数$x,y,c$表示操作区域为以第$x$行第$y$列为左上角的边长为$c$的正方形。
输出格式
输出一个$N\times M$的矩阵表示最后的棋盘。
样例
样例输入:
4 4 3
1 2 3 4
5 6 7 8
1 2 3 4
5 6 7 8
1 1 3
3 3 2
2 2 2
样例输出:
1 5 1 4
2 7 6 8
3 7 2 3
5 6 8 4
数据范围与提示
对于$30%$的数据,$N,M,Q\leqslant 100$。
对于另外$30%$的数据,保证所有$Q$个正方形两两之间不相交或相等。
对于$100%$的数据,$N,M,Q\leqslant 2,000$。所有数取值都为$0\sim 9$。
题解
$30\%$算法:
暴力更改即可。
时间复杂度:$\Theta(n^3)$。
期望得分:$30$分。
实际得分:$30$分。
$30\%pro$算法:
$whs$式毒瘤拆循环。
时间复杂度:$\Theta(n^3)$。
期望得分:$30$分。
实际得分:$60$分。
$30\%pro+$算法:
注意到所有的点都是$0\sim 9$,所以可以用$HZOI$式毒瘤字符读入输出。
时间复杂度:$\Theta(n^3)$。
期望得分:$30$分。
实际得分:$100$分。
$100\%$算法:
直接更改肯定会$TLE$,于是我们就来看一个新鲜的东西:十字链表。
简单来说,十字链表与普通链表的区别在于不仅记录了左右,而且记录了上下,于是我们只需要更改边缘一圈的值即可,但是代码实现相当繁琐,需要注意的细节较多。
时间复杂度:$\Theta(Q\times N\times $巨大的常数$)$。
期望得分:$100$分。
实际得分:$100$分。
代码时刻
$30\%pro+$算法:
#include<bits/stdc++.h>
int n,m,q;
char map[2050][2050];
int main()
{
scanf("%d%d%d",&n,&m,&q);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%s",&map[i][j]);
while(q--)
{
int x,y,c;
scanf("%d%d%d",&x,&y,&c);
int len=c-1;
while(len>0)
{
for(int i=0;i<len;i++)
{
char w1=map[x][y+i];
char w2=map[x+i][y+len];
char w3=map[x+len][y+len-i];
char w4=map[x+len-i][y];
map[x+i][y+len]=w1;
map[x+len][y+len-i]=w2;
map[x+len-i][y]=w3;
map[x][y+i]=w4;
}
len-=2;
x++;
y++;
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
printf("%c ",map[i][j]);
printf("\n");
}
return 0;
}
$100\%$算法:
#include<bits/stdc++.h> using namespace std; int n,m,q; int Map[5000][5000],wzc[5000][5000]; int p[5000000],wtf[5000000][4]; int cnt,tmp; int now,flag; int ls,rs,lx,rx,lsd,rsd,lxd,rxd; int main() { scanf("%d%d%d",&n,&m,&q); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&Map[i][j]); for(int i=0;i<=n+1;i++) for(int j=0;j<=m+1;j++) { wzc[i][j]=++cnt; p[cnt]=Map[i][j]; } for(int i=0;i<=n+1;i++) for(int j=0;j<=m+1;j++) { wtf[wzc[i][j]][0]=wzc[i-1][j]; wtf[wzc[i][j]][1]=wzc[i][j+1]; wtf[wzc[i][j]][2]=wzc[i+1][j]; wtf[wzc[i][j]][3]=wzc[i][j-1]; } while(q--) { int x,y,c; scanf("%d%d%d",&x,&y,&c); now=wzc[x][0]; flag=1; while(y--) { if(wtf[wtf[now][flag]][0]==now)tmp=0; if(wtf[wtf[now][flag]][1]==now)tmp=1; if(wtf[wtf[now][flag]][2]==now)tmp=2; if(wtf[wtf[now][flag]][3]==now)tmp=3; now=wtf[now][flag]; switch(tmp) { case 0:flag=2;break; case 1:flag=3;break; case 2:flag=0;break; case 3:flag=1;break; } } ls=now; lsd=flag; for(int i=1;i<c;++i) { if(wtf[wtf[now][flag]][0]==now)tmp=0; if(wtf[wtf[now][flag]][1]==now)tmp=1; if(wtf[wtf[now][flag]][2]==now)tmp=2; if(wtf[wtf[now][flag]][3]==now)tmp=3; now=wtf[now][flag]; switch(tmp) { case 0:flag=2;break; case 1:flag=3;break; case 2:flag=0;break; case 3:flag=1;break; } } flag=(flag+1)%4; rs=now; rsd=flag; for(int i=1;i<c;++i) { if(wtf[wtf[now][flag]][0]==now)tmp=0; if(wtf[wtf[now][flag]][1]==now)tmp=1; if(wtf[wtf[now][flag]][2]==now)tmp=2; if(wtf[wtf[now][flag]][3]==now)tmp=3; now=wtf[now][flag]; switch(tmp) { case 0:flag=2;break; case 1:flag=3;break; case 2:flag=0;break; case 3:flag=1;break; } } flag=(flag+1)%4; rx=now; rxd=flag; for(int i=1;i<c;++i) { if(wtf[wtf[now][flag]][0]==now)tmp=0; if(wtf[wtf[now][flag]][1]==now)tmp=1; if(wtf[wtf[now][flag]][2]==now)tmp=2; if(wtf[wtf[now][flag]][3]==now)tmp=3; now=wtf[now][flag]; switch(tmp) { case 0:flag=2;break; case 1:flag=3;break; case 2:flag=0;break; case 3:flag=1;break; } } flag=(flag+1)%4; lx=now; lxd=flag; for(int i=1;i<=c;++i) { int d1=wtf[rs][(rsd+3)%4]; int d2=wtf[rx][(rxd+3)%4]; int d3=wtf[lx][(lxd+3)%4]; int d4=wtf[ls][(lsd+3)%4]; int t1,t2,t3,t4; if(wtf[wtf[rs][(rsd+3)%4]][0]==rs)t1=0; if(wtf[wtf[rx][(rxd+3)%4]][0]==rx)t2=0; if(wtf[wtf[lx][(lxd+3)%4]][0]==lx)t3=0; if(wtf[wtf[ls][(lsd+3)%4]][0]==ls)t4=0; if(wtf[wtf[rs][(rsd+3)%4]][1]==rs)t1=1; if(wtf[wtf[rx][(rxd+3)%4]][1]==rx)t2=1; if(wtf[wtf[lx][(lxd+3)%4]][1]==lx)t3=1; if(wtf[wtf[ls][(lsd+3)%4]][1]==ls)t4=1; if(wtf[wtf[rs][(rsd+3)%4]][2]==rs)t1=2; if(wtf[wtf[rx][(rxd+3)%4]][2]==rx)t2=2; if(wtf[wtf[lx][(lxd+3)%4]][2]==lx)t3=2; if(wtf[wtf[ls][(lsd+3)%4]][2]==ls)t4=2; if(wtf[wtf[rs][(rsd+3)%4]][3]==rs)t1=3; if(wtf[wtf[rx][(rxd+3)%4]][3]==rx)t2=3; if(wtf[wtf[lx][(lxd+3)%4]][3]==lx)t3=3; if(wtf[wtf[ls][(lsd+3)%4]][3]==ls)t4=3; wtf[d1][t1]=ls; wtf[d2][t2]=rs; wtf[d3][t3]=rx; wtf[d4][t4]=lx; wtf[ls][(lsd+3)%4]=d1; wtf[rs][(rsd+3)%4]=d2; wtf[rx][(rxd+3)%4]=d3; wtf[lx][(lxd+3)%4]=d4; if(wtf[wtf[ls][lsd]][0]==ls)tmp=0; if(wtf[wtf[ls][lsd]][1]==ls)tmp=1; if(wtf[wtf[ls][lsd]][2]==ls)tmp=2; if(wtf[wtf[ls][lsd]][3]==ls)tmp=3; ls=wtf[ls][lsd]; switch(tmp) { case 0:lsd=2;break; case 1:lsd=3;break; case 2:lsd=0;break; case 3:lsd=1;break; } if(wtf[wtf[rs][rsd]][0]==rs)tmp=0; if(wtf[wtf[rs][rsd]][1]==rs)tmp=1; if(wtf[wtf[rs][rsd]][2]==rs)tmp=2; if(wtf[wtf[rs][rsd]][3]==rs)tmp=3; rs=wtf[rs][rsd]; switch(tmp) { case 0:rsd=2;break; case 1:rsd=3;break; case 2:rsd=0;break; case 3:rsd=1;break; } if(wtf[wtf[rx][rxd]][0]==rx)tmp=0; if(wtf[wtf[rx][rxd]][1]==rx)tmp=1; if(wtf[wtf[rx][rxd]][2]==rx)tmp=2; if(wtf[wtf[rx][rxd]][3]==rx)tmp=3; rx=wtf[rx][rxd]; switch(tmp) { case 0:rxd=2;break; case 1:rxd=3;break; case 2:rxd=0;break; case 3:rxd=1;break; } if(wtf[wtf[lx][lxd]][0]==lx)tmp=0; if(wtf[wtf[lx][lxd]][1]==lx)tmp=1; if(wtf[wtf[lx][lxd]][2]==lx)tmp=2; if(wtf[wtf[lx][lxd]][3]==lx)tmp=3; lx=wtf[lx][lxd]; switch(tmp) { case 0:lxd=2;break; case 1:lxd=3;break; case 2:lxd=0;break; case 3:lxd=1;break; } } } for(int i=1;i<=n;i++) { now=wzc[i][0]; flag=1; for(int j=1;j<=m;j++) { if(wtf[wtf[now][flag]][0]==now)tmp=0; if(wtf[wtf[now][flag]][1]==now)tmp=1; if(wtf[wtf[now][flag]][2]==now)tmp=2; if(wtf[wtf[now][flag]][3]==now)tmp=3; now=wtf[now][flag]; switch(tmp) { case 0:flag=2;break; case 1:flag=3;break; case 2:flag=0;break; case 3:flag=1;break; } printf("%d ",p[now]); } puts(""); } return 0; }
rp++