打印螺旋式方阵

package com.java;

public class PrintFangZhen {

	/**
	 * 打印等长的二维数组,要求从1開始的自然数由方阵的最外圈向内螺旋方式地顺序排列。 如: n = 4 则打印:
	 * 1 2 3 4
	 * 12 13 14 5
	 * 11 16 15 6
	 * 10 9 8 7
	 *
	 */
	public static void main(String[] args) {
		int n = 4;
		if (n <= 0) {
			System.out.println("n必须大于0!");
			return;
		}
		int[][] arr = method(n);
		traverse(arr);
	}

	/**
	 * 按从1開始的自然数由方阵的最外圈向内螺旋方式地顺序排列,并存到一个二维数组中
	 *
	 * @param n
	 *            这个方阵的边长
	 * @return 一个二维数组
	 */
	public static int[][] method(int n) {
		// 定义一个储存数字的二维数组
		int[][] arr = new int[n][n];
		// 定义一个count计数,count即为数组中的元素
		int count = 0;
		int i = 0, j = 0;
		while (true) {
			// 当n为1的时候,直接存入数组中并结束循环
			if (n == 1) {
				arr[0][0] = 1;
				break;
			}
			// 当一个元素的上、右、下、左的值不是0的时候;或者是当其上和右有值,而且左和下越界时,结束循环
			if ((i - 1 >= 0 && j + 1 <= n - 1 && i + 1 <= n - 1 && j - 1 >= 0
					&& arr[i - 1][j] != 0 && arr[i][j + 1] != 0
					&& arr[i + 1][j] != 0 && arr[i][j - 1] != 0)
					|| (j - 1 < 0 && i + 1 > n - 1 && arr[i - 1][j] != 0 && arr[i][j + 1] != 0)) {
				break;
			}
			// 假设上面的角标越界了,而且右面的角标没越界,则向右移动
			if ((i - 1 < 0 && j <= n - 1)) {
				arr[i][j++] = ++count;
			} else if (j + 1 > n - 1 && i + 1 <= n - 1) {
				// 假设右面的角标越界了,而且以下的角标没越界,则向下移动
				if (j == n) {
					j--;
				}
				i++;
				arr[i][j] = ++count;
			} else if (i + 1 > n - 1 && j - 1 >= 0) {
				// 假设以下的角标越界了,而且左边的角标没越界,则向左移动
				arr[i][--j] = ++count;
			} else if (j - 1 < 0 && i - 1 >= 0 && arr[i - 1][j] == 0) {
				// 假设左边的角标越界了,而且上边的角标没越界,而且上边的元素的值为0,则向上移动
				arr[--i][j] = ++count;
			} else {
				// 假设不是边缘,则按其它情况来计算
				if (arr[i - 1][j] != 0 && arr[i][j + 1] == 0) {
					// 假设右面元素的值为0,而且上面元素的值不为0,则向右移动
					arr[i][++j] = ++count;
				} else if (arr[i + 1][j] == 0) {
					// 假设以下元素的值为0,则向下移动
					arr[++i][j] = ++count;
				} else if (arr[i][j - 1] == 0) {
					// 假设左面元素的值为0,则向左移动
					arr[i][--j] = ++count;
				} else if (arr[i - 1][j] == 0) {
					// 假设上面元素的值为0,则向上移动
					arr[--i][j] = ++count;
				}
			}

		}
		return arr;
	}

	/**
	 * 遍历二维数组
	 *
	 * @param arr
	 *            一个待遍历的二维数组
	 */
	public static void traverse(int[][] arr) {
		for (int i = 0; i < arr.length; i++) {
			for (int j = 0; j < arr[i].length; j++) {
				System.out.print(arr[i][j] + " ");
			}
			System.out.println();
		}
	}

}
时间: 2024-10-14 13:13:46

打印螺旋式方阵的相关文章

c和c++的一些训练题(10)(打印螺旋方阵)

问题的提出:编写螺旋方阵.其中螺旋方阵形式如下: 1  12 11  10 2  13 16   9 3  14 15   8 4   5   6    7 设row,column分别代表行.列坐标,变量p从1到n2将p依次存入数组a[row][column]中,要确定row.colomn的变化情况.分析如下:引进变量k,初值为n.当数据存入到左下角或右上角时,k减1,这样可保证输出时方阵.引进变量t,初值为1,当数据存入到右下角时,令t改变符合,当存入到左上角时,t又改变符合,这样可保证赋值到

奇数阶魔方阵

原题 打印魔方阵,魔方阵是指这样的方针,每一行.每一列以及对角线的和相等.例如三阶魔方阵: 8 1 6 3 5 7 4 9 2 编程打印奇数阶魔方阵. 提示 问题解决的关键是元素的填充,第一个元素1的位置在第一行正中,新的位置应该处于最近插入元素的右上方:但如果右上方的位置超出方针上边界,则新的位置应该取列的最下一个位置:超出右边界则取行的最左的一个位置:若最近插入的元素为n的整数倍,则选下面一行同列上的位置为新的位置. 实现代码 /*******************************

拉丁方阵问题

问题描述: 拉丁方阵是一种n×n的方阵,方阵中恰有n中不同的元素,每种元素恰有n个,并且每种元素在一行和一列中恰好出现一次.著名数学家和物理学家欧拉使用拉丁字母来做为方阵里元素的符号,拉丁方阵因此而得名. 问题分析: 用循环链表来实现 实现代码(c): #include<stdio.h> #include<stdlib.h> typedef struct Node { int data; struct Node *next; }Node; typedef struct Node *

算法:拉丁方阵(Latin Square)

拉丁方阵(英语:Latin square)是一种 n × n 的方阵,在这种 n × n 的方阵里,恰有 n 种不同的元素,每一种不同的元素在同一行或同一列里只出现一次.以下是两个拉丁方阵举例: 拉丁方阵有此名称是因为瑞士数学家和物理学家欧拉使用拉丁字母来做为拉丁方阵里的元素的符号. 算法步骤: 在第一行中,数字从 1 到 n 连续存储. 第二行,数字向右移动一列.即 1 现在存储在第二列,依此类推. 在第三行中,数字向右移动两列.即 1 现在存储在第三列,依此类推. 对于其余的行,我们将以相同

c算法题

找出一个字符串中最长重复次数的子字符串,并计算其重复次数.例如:字符串“abc fghi bc kl abcd lkm abcdefg”,并返回“abcd”和2. 由于题目要求寻找至少重复2次的最长的子字符串,重点在于最长的子字符串,而不在于重复的最多次数.因此我们可以从长度最长的字符串入手,计算其重复次数.只要重复达到2次,即可返回该字符串. #include <stdio.h> #include <stdlib.h> #include <string.h> int

算法:九宫格问题--奇数阶魔方(Magic-Square)

一.魔方介绍 魔方(这里是简称,也可以叫幻方.魔术矩阵,Magic Square)是 n×n 正方形网格(n 为每侧的单元数),里面每个单元格填充了不同的正整数 1, 2, 3, ... , n2,并且每一行.每一列和对角线中的正整数之和相等.每行.每列以及对角线上的单元格里的正整数之和又叫做魔术常数或魔方的魔术和. 幻方历史: <系辞>云:“河出图,洛出书,圣人则之.”在宋朝之前,洛书的记述只有文字. 九宫图实物最早发现于西汉,1977年中国考古学家在安徽阜阳县双古堆西汉古墓中发现汉文帝七年

打印一个N*N的方阵,从最外层到最里层每层一个字符

/*打印一个N*N的方阵,N为每边字符的个数( 3〈N〈20 ),要求最外层为“X”,第二层为“Y”,从第三层起每层依次打印数字0,1,2,3,... 例子:当N =5,打印出下面的图形: X X X X X X Y Y Y X X Y 0 Y X X Y Y Y X X X X X X */ 1 // TESTC.cpp : 定义控制台应用程序的入口点. 2 // 3 4 #include "stdafx.h" 5 #include <string>//当要使用strin

【模板小程序】循环方阵构造(仿《剑指offer》循环矩阵打印)

1 /* 2 本程序说明: 3 4 输入:方阵大小n,输出:n*n的旋转方阵 5 6 举例: 7 当n=2时,输出: 8 1 2 9 4 3 10 当n=4时,输出: 11 1 2 3 4 12 12 13 14 5 13 11 16 15 6 14 10 9 8 7 15 16 */ 17 #include <iostream> 18 #include <vector> 19 20 using namespace std; 21 22 void PrintMatrixInCirc

从右上角到左下角沿反对角线打印方阵中的元素

问题描述:从右上角到左下角沿反对角线打印方阵中的元素.假设矩阵为: 1,2,3,4 5,6,7,8 9,10,11,12 13,14,15,16 输出:4,3,8,2,7,12,1,6,11,16,5,10,15,9,14,13, 分析:这个没有什么算法问题,就是纯粹的代码技巧问题,通过画图可以找出规律,只要确定每条反对角线的两端的坐标,就可以打印出对角线上的元素.因此可以将其分成两部分打印,定义两个变量row和column来保存矩阵的行数和列数,定义两个变量x和y来作为临时坐标变量.可确定出两