题目描述
看着这样的"回”形图案你晕吗?让我们不用数组,来做出它。
输入格式:n。正方形的边长
输出格式:"%3d"
边长为 n 的数字回形方阵。
解题思路
我们要想直接根据坐标来得到对应的数值是不容易的,但如果我们根据数值来求出对应的坐标会更加简单一些。我们可以对k遍历1~n²,每次循环对坐标(i,j)进行一次操作,使(i,j)的移动轨迹为所要求的“回”字形即可,此时k对应的(i,j)即为其所要输出的坐标。
如何实现“回”字形轨迹:定义一个变量表示坐标移动方向,定义四个变量表示上下左右边界,当坐标移动到边界时,方向改变,同时对应边界向中心移动一格
根据这个我们可以定义一个函数传入n和坐标,返回坐标对应输出的值
int evaluate(int x,int y,int n){
int direction=0; //数组移动方向 0:向右 1:向下 2:向左 3:向上
int left=0,right=n-1,up=1,down=n-1;//移动边界 如果碰到移动边界就转向, 并且该移动边界缩小
int i=0,j=0;//初始化坐标为(0,0)
for(int k=1;k<=n*n;k++){
if(x==i && y==j){
return k;
}
//坐标移动
switch(direction){
case 0:i++;
break;
case 1:j++;
break;
case 2:i--;
break;
case 3:j--;
break;
}
//判断是否到边界,如果到就改变方向
if(direction==0 && i==right) {
right--;
direction++;
}else if(direction==1 && j==down){
down--;
direction++;
}else if(direction==2 && i==left){
left++;
direction++;
}else if(direction==3 && j==up){
up++;
direction=0;
}
}
}
完整代码实现
#include<stdio.h>
int evaluate(int x,int y,int n){
int direction=0; //数组移动方向 0:向右 1:向下 2:向左 3:向上
int left=0,right=n-1,up=1,down=n-1;//移动边界 如果碰到移动边界就转向, 并且该移动边界缩小
int i=0,j=0;//初始化坐标为(0,0)
for(int k=1;k<=n*n;k++){
if(x==i && y==j){
return k;
}
//坐标移动
switch(direction){
case 0:i++;
break;
case 1:j++;
break;
case 2:i--;
break;
case 3:j--;
break;
}
//判断是否到边界,如果到就改变方向
if(direction==0 && i==right) {
right--;
direction++;
}else if(direction==1 && j==down){
down--;
direction++;
}else if(direction==2 && i==left){
left++;
direction++;
}else if(direction==3 && j==up){
up++;
direction=0;
}
}
}
int main(){
int n;
scanf("%d",&n);
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
printf("%3d",evaluate(j,i,n));
}
printf("\n");
}
return 0;
}