B - Grid Rotations (atcoder.jp)
SOLUTION
我表示大为不理解。。。。这个简单🍳题把我坑🕳惨了
首先我们可以知道每一行/列的数不会发生错位(证明显然)
通过样例观察法,我们可以发现:
最终每一行/列的数是原来正序/倒序的循环
证明:
以一维数组为例:
1 2 3 | 4 5 6 7
→ \to → 3 2 1 | 7 6 5 4
3 2 1 7 | 6 5 4
→ \to → 7 1 2 3 | 4 5 6
因为每一次进行
翻转
操作最边边的两个数会挨在一起ヽ( ̄ω ̄( ̄ω ̄〃)ゝ
而且他们原本在P上就是挨在一起的
因为最边边的要么是原本的开头和结尾
要么就是从中间剖开的
(这两种情况在P上都是)
剩下的数倒序
这样就导致了每次操作都会使顺序颠倒一次+滚动更新
因此我们记录第1行和第一列更新后的位置
然后根据q的奇偶判断滚动/顺序情况
(具体见下代码)
CODE
#include<iostream>
using namespace std;
const int N=5e5+2;
int A,B,q,x,y,n,m;
char a[N],ans[N];
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%s",a+(i-1)*m+1);
}
x=1,y=1;
cin>>q;
for(int i=1;i<=q;i++){
cin>>A>>B;
x=(n+A-x+1)%n;
y=(m+B-y+1)%m;
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
int X,Y;
if(q&1) X=(x-i+1+n)%n,Y=(y-j+1+m)%m;
else X=(x+i-1+n)%n,Y=(y+j-1+m)%m;
if(!X)X=n;
if(!Y)Y=m;
ans[m*(X-1)+Y]=a[(i-1)*m+j];
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
printf("%c",ans[(i-1)*m+j]);
}
printf("\n");
}
return 0;
}
w完结撒花❀
★,°:.☆( ̄▽ ̄)/$:.°★ 。