一.链接及题目
二.分析
读完题目后可以分析出来这道题基本解法就是模拟,数据范围不大,应当是不会超时。
第一个要处理的问题是查找数字k-1的问题,对于这种固定的问题,一般的处理方法是写一个函数,这里我们命名为find(),只需要对我们新建的“地图”进行遍历,找到即可停止。
第二个要处理的问题是填写数字k的问题,既然题目上对填写要求分了四种情况,那么我们就可以单独写一个函数去处理填写的问题,分别对下一个数字要填写的位置进行更新,这里我们将变量命名为stuffi,stuffj。
第三个要处理的问题是细节问题,为了方便理解和书写,我们只用到了二维数组里面索引为大于等于1的部分,经过分析推导可以得到,当输入一个奇数n时,数字1根据规则一定会填写到[1][n/2+1]另外还需要规定边界,以免遍历的过程中越界。
三.代码
#include <iostream>
#include <cmath>
#include <cstdio>
const int M=50;
using namespace std;
int n,rb,downb; //rb代表右边界,downb代表下边界
int map[M][M]; //初始地图
int stuffi,stuffj; //填充数字K的位置
void calculate(int ii,int jj){
stuffi=stuffj=0; //初始化
if(ii==1&&jj!=n){ //若k-1在第一行但不在最后一列
stuffi=n;
stuffj=jj+1;
return;
}else if(jj==n&&ii!=1){ //若k-1在最后一列但不在第一行
stuffi=ii-1;
stuffj=1;
return;
}else if(ii==1&&jj==n){ //若k-1在第一行最后一列
stuffi=2;
stuffj=jj;
return;
}else if(ii!=1&&jj!=n){ //若k-1既不在第一行,也不在最后一列
if(map[ii-1][jj+1]==0&&ii-1>0&&jj+1<=n){ //未填数
stuffi=ii-1;
stuffj=jj+1;
return;
}else{ //填数
stuffi=ii+1;
stuffj=jj;
return;
}
}
return;
}
void find(int x){
for(int i=1;i<=downb;i++){ //对map进行遍历,查找K-1所在的位置
for(int j=1;j<=rb;j++){
if(map[i][j]==x){
calculate(i,j); //找到后进行计算判断
return;
}
}
}
}
int main(){
cin>>n;
rb=n; //规定边界
downb=n; //规定边界
map[1][n/2+1]=1; //填写数字1
for(int k=2;k<=n*n;k++){
find(k-1); //查找数字K-1
map[stuffi][stuffj]=k;
}
//输出
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++) cout<<map[i][j]<<" ";
cout<<endl;
}
return 0;
}
此解法并不是最优解,但适合初学者理解,感谢理解!