题解:B4199 [常州市赛 2020] 旋转数塔
wenqinghua1001 · · 题解
思路
不难发现,从外面数,奇数圈是顺时针填数,偶数圈是逆时针填数,只需一层一层暴力即可。
设
顺时针
如果顺时针,那么把这一圈分为四份。上面这幅图最外面的一层,分为四份就是:
第一份:
可以找到其中的规律,第一份列数增加,第二份行数增加,第三份列数减少,第四份行数减少。
void dfs1(int r){
for(int i=1;i<=r;i++){
a[x][y]=++sum;
y++;
}
for(int i=1;i<=r;i++){
a[x][y]=++sum;
x++;
}
for(int i=1;i<=r;i++){
a[x][y]=++sum;
y--;
}
for(int i=1;i<=r;i++){
a[x][y]=++sum;
x--;
}
x++,y++;// 为下一层做准备。
}
逆时针
如果逆时针,那么也把这一圈分为四份。这幅图从外面数的第二层,分为四份就是:
第一份:
可以找到其中的规律,第一份行数增加,第二份列数增加,第三份行数减少,第四份列数减少。
int dfs2(int r){
for(int i=1;i<=r;i++){
a[x][y]=++sum;
x++;
}
for(int i=1;i<=r;i++){
a[x][y]=++sum;
y++;
}
for(int i=1;i<=r;i++){
a[x][y]=++sum;
x--;
}
for(int i=1;i<=r;i++){
a[x][y]=++sum;
y--;
}
x++,y++;// 为下一层做准备。
}
代码
AC 记录
#include<bits/stdc++.h>
using namespace std;
int a[101][101],sum=0,x=1,y=1;
void dfs1(int r){
for(int i=1;i<=r;i++){
a[x][y]=++sum;
y++;
}
for(int i=1;i<=r;i++){
a[x][y]=++sum;
x++;
}
for(int i=1;i<=r;i++){
a[x][y]=++sum;
y--;
}
for(int i=1;i<=r;i++){
a[x][y]=++sum;
x--;
}
x++,y++;// 为下一层做准备。
}
int dfs2(int r){
for(int i=1;i<=r;i++){
a[x][y]=++sum;
x++;
}
for(int i=1;i<=r;i++){
a[x][y]=++sum;
y++;
}
for(int i=1;i<=r;i++){
a[x][y]=++sum;
x--;
}
for(int i=1;i<=r;i++){
a[x][y]=++sum;
y--;
}
x++,y++;// 为下一层做准备。
}
int main(){
int n;
cin>>n;
if(n%2==1) a[n/2+1][n/2+1]=n*n;
for(int i=n-1,j=1;i>=1;i-=2,j++){
if(j%2==1){
// 顺时针
dfs1(i);
}
else{
// 逆时针
dfs2(i);
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++)
cout<<a[i][j]<<" ";
cout<<endl;
}
return 0;
}