回形数
问题分析
- 首先是观察其顺序,不难看出
- 左上到左下 左下到右下 右下到右上 右上到左上
- 既然这样,我们就按这个逻辑去输入就好了,
- 为了简化问题,在实现中就将已经输出过的点,打上标记,不再输出,从而降低了实现时,对于边界条件把握的难度
实践环节
- 在手写的时候,发现输出格式的有关规定,特意就把输出封装为一个函数,对于格式进行统一处理
- 既然,知道了顺序,就按照顺序去输入,
- 通过观察实例,即有了逐层输出这一想法
- 那就动手去做,难点就在于对于每个方向,进行输出时,其起始坐标
- 这个我们可以自己手动画个图,实际操作一下,不难发现规律
- 下面我的注释中也有写到一些
- 还有一点就是输出某个方向时,要注意,其是递增还是递减
可优化点
- 其实一开始的标记,的确起来很多的作用
- 但是拖延了代码的效率
- 对于标记,这个问题,可以通过对于每个for循环,输出每个方向的时候,通过当前层数,给予每个for循环的判断标准
- 例如,当时左下到有下时,for循环结束条件可以设置为,横轴长度-层数-1
- 笔者,在此偷个懒,就不写了。哈哈哈。ac,ac
import java.util.Scanner;
public class Main
{
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int i = scanner.nextInt();
int j = scanner.nextInt();
int[][] a = new int[i][j];
for (int k = 0; k < a.length; k++) {
for (int k2 = 0; k2 < a[k].length; k2++) {
a[k][k2] = scanner.nextInt();
}
}
s(a);
}
/**
*
* @Description 用于按照要求格式,输出元素,这里将已经输出过的元素打上标记,避免下次再使用
* @author duanran
* @date 2020-3-22下午07:58:05
* @param a
* @param i
* @param j
*/
public static void print(int[][] a,int i,int j){
if (a[i][j]!=Integer.MAX_VALUE) {
System.out.print(a[i][j]+" ");
a[i][j] = Integer.MAX_VALUE;
}
}
/**
*
* @Description 用于循环回形数 从四个方向依次输出 左上到左下 左下到右下 右下到右上 右上到左上
* @author duanran
* @date 2020-3-22下午07:59:07
* @param a 回形数 矩阵
*/
public static void s(int[][] a) {
int i = a.length; // 竖轴长度
int j = a[0].length; // 横轴长度
int k = 0; // 层数,从外到内分别是0,1,2,3。。。。
/*
* 当且仅当输完一层 后还有下一层
* 水平方向输入完一次后少两行
* 竖直方向同理
*/
while (2*k<j&&2*k<i) {
// 左上到左下,纵坐标不变,变横坐标,当前的层数刚好是纵坐标,也是横坐标的起始坐标
for (int k2 = k; k2 < i; k2++) {
print(a, k2, k);
}
// 左下到右下,横坐标不变,变纵坐标,横坐标= 纵轴长度-层数-1 (-1是为了取的下标,因为下标从0开始)
// 纵坐标的起始坐标也是当前层数
for (int k2 = k; k2 < j; k2++) {
print(a, i-k-1, k2);
}
// 右下到右上,纵坐标不变,横坐标变,纵坐标 = 横轴长度-层数-1
// 横坐标的起始坐标是 纵轴长度-层数-1
for (int k2 = i-k-1; k2 >=0; k2--) {
print(a, k2, j-k-1);
}
// 右上到左上 横坐标不变,纵坐标变 ...
for (int k2 = j-k-1; k2 >= 0; k2--) {
print(a, k, k2);
}
// 层数加1,准备进入下一层
k++;
}
}
}
其他的题,也都有整理,可以看我的博客 断然不然嘞?