题目描述
在一个N*N的方阵中,填入1,2,……N * N个数,并要求构成如下的格式:
例如:
N=5
13 14 15 16 1
12 23 24 17 2
11 22 25 18 3
10 21 20 19 4
9 8 7 6 5
其中每行每个数据之间有一个空格,而行首和行尾没有多余空格。
输入格式
每个测试文件只包含一组测试数据,每组输入一个N。N的范围在1-50之间,输入错误及超出范围输出"Input data error",停止运行。
提示 注意:使用异常捕获非整数数据输入。
我的思路:
观察矩阵的形成,发现相当于矩阵构成类似一个个口字形,从外到内填充,类似于一堵堵“墙”,不断包围。
把每一堵“墙”独立来看,相当于先往下填充,到达边界后往左,往上,往右,这个步骤会重复几遍与输入的n有关,n=1时易知执行一遍,n=2时也执行一遍,n=3时执行2遍,易知重复次数 = (n+1)/2。
于是创建方法addwall,需要的参数是二维数组,起始位置的值,以及该位置的行数和列数,在主函数中使用for循环,根据“墙”的数量调用。
代码如下
import java.util.*;
import java.util.InputMismatchException;
public class Main {
public static void main(String args[]){
int i,j;
Scanner sc = new Scanner(System.in);
int n = 0; //局部变量需要初始化
try{
n = sc.nextInt();
}catch(InputMismatchException e){
System.out.println("Input data error");
System.exit(0);
}//对于输入非整数的处理
if(n < 1 || n > 50){
System.out.println("Input data error");
System.exit(0);
}
int array[][] = new int[n][n];
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
array[i][j] = 0;
}
}//初始化数组为0
array[0][n-1] = 1;//把起始点的值设为1
int num_wall = (n+1)/2;
i = 0;j = 1;
for(;num_wall >0 ;num_wall--){
array = addwall(array,i,n-j,n);
i++;
j++;
//每一堵墙的起始位置的坐标
}
for (i = 0; i < n; i++) {
for (j = 0; j < n-1; j++) {
System.out.print(array[i][j]+" ");
}
System.out.println(array[i][n-1]);
}
}
public static int[][] addwall(int[][] a,int line,int row,int n){
int i=0,j=0;
if(a[line][row]!=1){
a[line][row] = a[line-1][row]+1;//每一堵墙的起始值
}
while(line+1 < n && a[line+1][row] == 0){
a[line+1][row] = a[line][row]+1;//往下走 +1
line = line+1;//更新当前位置
}
while((row-1) >= 0 && a[line][row-1] == 0){
a[line][row-1] = a[line][row]+1;//往左走 +1
row = row-1;
}
while((line-1) >= 0 &&a[line-1][row] == 0 ){
a[line-1][row] =a[line][row]+1;//往上走 +1
line = line-1;
}
while((row+1) < n && a[line][row+1] == 0 ){
a[line][row+1] =a[line][row]+1;//往右走 +1
row = row+1;
}
return a;
}
}
一些低级bug:
1.最开始写addwall方法的时候没有定义为static,导致main方法无法调用
2.在设定边界时候,先判断是否array[line][row+1]==0,再判断row+1>n,导致出现了数组越界问题