0%

ABC-375-C -Spiral Rotation

题目大意

给定一个 N×NN \times N 的网格字符矩阵。对于每个 ii (1leileN/21 le i le N/2),将以 (i,i)(i, i) 为左上角、(N+1i,N+1i)(N+1-i, N+1-i) 为右下角的正方形区域顺时针旋转 90 度。求最终的网格状态。

image

这题其实纯模拟是做不出来的,需要一些小的优化技巧(如上图)

更加具象化一点是这样

image

AC代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>
using namespace std;
typedef long long ll;
const int N=3010;
int n;
char g[N][N],ans[N][N];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++) {
for(int j=1;j<=n;j++)
cin>>g[i][j];
}
for(int i=1;i<=n;i++) {
for(int j=1;j<=n;j++) {
int d=min(min(n+1-i,i),min(n+1-j,j)); // 即从该点到最近边框的距离
int x=i,y=j;
for(int _=1;_<=(d%4);_++) {
int xi=y,yj=n+1-x;
x=xi,y=yj;
}
ans[x][y]=g[i][j];
}
}
for(int i=1;i<=n;i++) {
for(int j=1;j<=n;j++) {
cout<<ans[i][j];
}
cout<<endl;
}
return 0;
}
// AC https://atcoder.jp/contests/abc375/submissions/58737053

纯模拟的TLE代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <iostream>
#include <set>
#include <vector>
#include <cmath>
#include <algorithm>
#include <iomanip>
using namespace std;
typedef long long ll;
const int N=3010;
int n;
char g[N][N],ans[N][N];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++) {
for(int j=1;j<=n;j++)
cin>>g[i][j];
}
for(int i=1;i<=n/2;i++) {
for(int x=i;x<=n+1-i;x++) {
for(int y=i;y<=n+1-i;y++) {
ans[y][n+1-x]=g[x][y];
}
}
for(int x=i;x<=n+1-i;x++) {
for(int y=i;y<=n+1-i;y++) {
g[y][n+1-x]=ans[y][n+1-x];
}
}
}
for(int i=1;i<=n;i++) {
for(int j=1;j<=n;j++) {
putchar(g[i][j]);
}
putchar('\n');
}
return 0;
}
// https://atcoder.jp/contests/abc375/submissions/58711404