首页 > 试题广场 >

编程输出以下格式的数据。 when i=1:

[问答题]

编程输出以下格式的数据。

when i=1:

1
4   5   2
3

when i=2:

1   2
8   9  10   3

7  12 11  4
6   5
办法可能有点土哈
public class Circulate {
    public static void main(String[] args) {
        Circulate c = new Circulate();
        c.sort();
    }
    int i = 2;
    static int j = 1;
    int[][] s = new int[i + 2][i + 2];
    // 定义坐标
    int x = i + 1, y = 0;
    // 位移函数
    public void up(int k, int l) {
        this.x = k - 1;
        this.y = l;
    }
    public void right(int k, int l) {
        this.x = k;
        this.y = l + 1;
    }
    public void left(int k, int l) {
        this.x = k;
        this.y = l - 1;
    }
    public void down(int k, int l) {
        this.x = k + 1;
        this.y = l;
    }
    public void sort() {
        // 第1行
        for (int k = 0; k < i; k++) {
            s[0][k] = j++;
        }
        // 第2~倒数第2行首末位
        for (int k = 1; k <= i; k++) {
            s[k][i + 1] = j++;
        }
        // 最后一行
        for (int k = i - 1; k >= 0; k--) {
            s[i + 1][k] = j++;
        }
        // 内部循环
        int l = i, n = 0;
        while (l != 0 && j < (4 * i + i * i)) {
            for (int k = 1; k <= l; k++) {
                up(x, y);
                s[x][y] = j++;
            }
            n++;
            if (n % 2 == 0)
                l--;
            for (int k = 1; k <= l; k++) {
                right(x, y);
                s[x][y] = j++;
            }
            n++;
            if (n % 2 == 0)
                l--;
            for (int k = 1; k <= l; k++) {
                down(x, y);
                s[x][y] = j++;
            }
            n++;
            if (n % 2 == 0)
                l--;
            for (int k = 1; k <= l; k++) {
                left(x, y);
                s[x][y] = j++;
            }
            n++;
            if (n % 2 == 0)
                l--;
        }
        // 输出
        for (int k = 0; k < i + 2; k++) {
            for (int o = 0; o < i + 2; o++) {
                String m;
                if (s[k][o] == 0) {
                    m = " ";
                } else
                    m = s[k][o] + "";
                System.out.print(m + " ");
            }
            System.out.println();
        }
    }
}

编辑于 2017-10-09 21:30:23 回复(2)

我的想法是把第一行,最后一行以及最后一列拿出来,剩下的部分就是一个i*i的螺旋数组,然后就好办了.

另一种思路就是整体看作一个(i+2)*(i+2)的螺旋数组.当遍历到第一行和最后一行的两项时跳过赋值,其他不变.输出时同样跳过就可以了.


package printTest;
import java.util.Scanner;
public class printTest {
    public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    System.out.println("input a number :");
    int n = scanner.nextInt();
    int[][] arr = new int[n + 2][n + 2];
    int value = 1;
    /**
     * 将最外边拿出来单独处理
     */
    for (int i = 0; i < n; i++)
        arr[0][i] = value++;
    for(int i=1;i<=n;i++)
        arr[i][n+1]=value++;
    for (int i = n; i > 0; i--)
        arr[n + 1][i-1] = value++;
    for (int i = n; i > 0; i--)
        arr[i][0] = value++;
    int start, end, top, bottom;
    start = top = 1;
    end = bottom = n;
    /**
     * 输出螺旋数组
     */
    while (start<end||top<bottom) {
        for (int i = start; i <= end; i++)
        arr[top][i] = value++;
        top++;
        for (int i = top; i <= bottom; i++)
        arr[i][end] = value++;
        end--;
        for (int i = end; i >= start; i--)
        arr[bottom][i] = value++;
        bottom--;
        for (int i = bottom; i >= top; i--)
        arr[i][start] = value++;
        start++;
    }
    /**
     * 如果i是奇数要将中间一位单独处理
     * i为偶数则不需要
     */
    if (n % 2 == 1)
        arr[(n+1)/2][(n+1)/2] = value;
    /**
     * 打印数组输出结果
     */
    System.out.println("result is :");
    for (int i = 0; i < arr[0].length - 2; i++)
        System.out.print(arr[0][i] + "\t");
    System.out.println("");
    for (int i = 1; i < arr.length-1 ; i++) {
        for (int j = 0; j < arr[0].length; j++)
        System.out.print(arr[i][j] + "\t");
        System.out.println("");
    }
    for (int i = 0; i < arr[0].length - 2; i++)
        System.out.print(arr[n+1][i] + "\t");
    }
}

i等于3时
i等于4时
i等于7时

发表于 2018-05-08 14:43:00 回复(0)

public class Spiral {

    private static int number = 1;
    private static int turns = 1;
    private static int innerTurns = 0;
    public static void main(String[] args) {
        int init = 8;
        int[][] ints = new int[init+2][init+2];
        ints = getSpiralArray(ints,init);
        System.out.println("When: init = " + init + ":");
        for (int i = 0; i < init+2; i++) {
            for (int j = 0; j < init+2; j++) {
                if(!((i == 0 || i == init+1) && j >= init)){
                    System.out.print(ints[i][j] + " ");
                }
            }
            System.out.println();
        }
    }
    private static int[][] getSpiralArray(int[][] ints,int i){
        while(number<=i4){//制造最外圈
            if(number<=i)
                ints[0][number-1] = number;
            else if(number<=2
i)
                ints[number-i][i+1] = number;
            else if(number<=3i)
                ints[i+1][3
i-number] = number;
            else
                ints[4i+1-number][0] = number;
            number++;
        }
        int sideLength = i - turns - innerTurns;
        int startNum = number - 1;
        while (number <= startNum+sideLength
4 ){//制造内圈
            for (int j = 0;j<sideLength;j++){
                if (number <= startNum + sideLength){
                    ints[turns][turns+j] = number;
                }
                else if (number <= startNum + sideLength2){
                    ints[turns+j][i-turns+1] = number;
                }
                else if (number <= startNum + sideLength
3){
                    ints[i-turns+1][i-turns+1-j] = number;
                }
                else
                    ints[i-turns+1-j][turns] = number;
                number++;
            }
        }
        turns++;
        innerTurns++;
        if(turns <= Math.ceil(i/2)){
            ints = getSpiralArray(ints,i);//递归生成内圈
        }
        if(i%2 == 1){
            ints[i/2 + 1][i/2 + 1] = i4 + ii;//奇数补中心
        }
        return ints;
    }

}


发表于 2018-03-02 21:14:12 回复(0)
思路:1.顺时针绕圈螺旋,由外圈到内圈
           2.从第一行第一个数开始计数绕圈,每走一步值加一
           3.难点在于输入i奇偶数时规律有些不同、随i变化阵列个数
           4. 最外圈和其他内圈分开处理
           5. 方法:用矩形数组做阵列载体,顺时针从上-右-下-左,从外圈到内圈,由1递增赋值
代码:
     class Program
    {
        static void Main(string[] args)
        {
            char ch;
            do
            {
                Console.Write("please enter i: ");
                ch = Console.ReadKey().KeyChar;
                Console.WriteLine();
                try
                {
                    //i值
                    int input = int.Parse(ch.ToString());
                    //行数
                    int row = 2 + input;
                    //阵列个数总数
                    //input值为偶数时
                    int sum = sum = (2 * input)* (input + 1);
                    //input值为奇数时
                    if(input % 2 == 1)
                    {
                       sum += 1;
                    }
                    //创建row维数组
                    int[][] arr = new int[row][];
                    //中间数组列数
                    int middle = (sum - 2 * input) / (row - 2);
                    for (int i = 0; i < arr.Length; i++)
                    {
                        //首、尾数组列数等于input
                        if (i == 0 || i == arr.Length - 1)
                        {
                            arr[i] = new int[input];
                        }
                        //中间数组列数等于middle
                        else
                        {
                            arr[i] = new int[middle];
                        }
                    }
                    //初始值
                    int val = 1;
                    //螺旋圈数
                    int count;
                    if (input == 1)
                    {
                        count = 1;
                    }
                    else
                    {
                        count = row / 2;
                    }
                    for (int i = 0; i < count; i++)
                    {
                        //最外圈特殊处理
                        if (i == 0)
                        {
                            //上边
                            for (int k = 0; k < arr[0].Length; k++)
                            {
                                arr[0][k] = val;
                                val++;
                            }
                            //右边
                            for (int k = 1; k < row - 1; k++)
                            {
                                arr[k][arr[k].Length - 1] = val;
                                val++;
                            }
                            //下边
                            for (int k = arr[row - 1].Length - 1; k >= 0; k--)
                            {
                                arr[row - 1][k] = val;
                                val++;
                            }
                            //左边
                            for (int k = row - 1 - 1; k > 0; k--)
                            {
                                arr[k][0] = val;
                                val++;
                            }
                        }
                        //内圈
                        else
                        {
                            //上边
                            for (int k = i; k < middle - i; k++)
                            {
                                arr[i][k] = val;
                                val++;
                            }
                            //右边
                            for (int k = 0; k < row - 2 * (i + 1); k++)
                            {
                                arr[i + 1 + k][middle - 1 - i] = val;
                                val++;
                            }
                            //下边
                            for (int k = middle - 1 - i; k >= i; k--)
                            {
                                arr[row - 1 - i][k] = val;
                                val++;
                            }
                            //左边
                            for (int k = 0; k < row - 2 * (i + 1); k++)
                            {
                                arr[row - 1 - 1 - i - k][i] = val;
                                val++;
                            }
                        }               
                    }
                    //奇数最内行补齐数
                    if (input % 2 == 1)
                    {
                        for (int k = count; k < middle - count; k++)
                        {
                            arr[row / 2][k] = val;
                            val++;
                        }
                    }
                    //输出
                    for (int i = 0; i < arr.Length; i++)
                    {
                        for (int k = 0; k < arr[i].Length; k++)
                        {
                            Console.Write(arr[i][k] + "\t");
                        }
                        Console.WriteLine();
                    }
                }
                catch
                {

                }
            }
            while (ch.ToString().ToUpper() != "Q");           
        }    
    }
运行结果:



发表于 2018-04-10 21:22:39 回复(2)
解题思路:把此方阵当成(i+2)*(i+2)的螺旋矩阵,然后赋值的时候第一行和最后一行最后两个元素跳过,遍历数组的时候也跳过!boolean为ture时为正序打印,false为逆序打印!
public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入一个整数:");
        int num = scanner.nextInt()+2;
        int[][] array = getArray(num, true);
        System.out.println("打印结果为:");
        for (int i = 0; i < array.length; i++) {
            for (int j = 0; j < array.length; j++) {
                if (array[i][j]==array[0][array.length-1]||array[i][j]==array[0][array.length-2]
                ||array[i][j]==array[array.length-1][array.length-1]
                        ||array[i][j]==array[array.length-1][array.length-2]){
                    continue;
                }else {
                    System.out.print(array[i][j] + "\t");
                }
            }
            System.out.println();
        }
    }
    private static int[][] getArray(int n,boolean flag){
        int[] numArray = new int[n * n - 4];
        for (int i = 0; i < numArray.length; i++) {
            if (flag){
                numArray[i]=i+1;
            }else {
                numArray[i]=numArray.length-i;
            }
        }
        for (int i = 0; i < numArray.length; i++) {
            System.out.print(numArray[i]+"\t");
        }
        System.out.println();
        int index=0;
        int[][] arr = new int[n][n];
        //确定层数

        int num=n%2==0?n/2:n/2+1;
        for (int i = 0; i < num; i++) {
            // 从左到右
            for (int j = i; j < n-i; j++) {
                if (i==0&&(j==n-i-1||j==n-i-2)){
                    continue;
                }else {
                    arr[i][j]=numArray[index++];
                }
            }
            // 从上到下
            for (int j = i+1; j < n-i; j++) {
                if (i==0&&j==n-i-1){
                    continue;
                }else {
                    arr[j][n - i - 1] = numArray[index++];
                }
            }
            // 从右到左
            for (int j = n-i-2; j >=i; j--) {
                if (i==0&&j==n-i-2){
                    continue;
                }else {
                    arr[n-i-1][j]=numArray[index++];
                }
            }
            // 从下到上
            for (int j = n-i-2; j >i; j--) {
                arr[j][i]=numArray[index++];
            }
        }
        return arr;
    }
请输入一个整数:
3
flag=true时打印结果为:
1 2 3
12 13 14 15 4
11 20 21 16 5
10 19 18 17 6
9 8 7
flag=false时打印结果为:
21    20    19    
10    9    8    7    18    
11    2    1    6    17    
12    3    4    5    16    
13    14    15    

编辑于 2019-09-03 02:40:43 回复(0)
import itertools

def spiral(init):
    status = itertools.cycle(['right', 'down', 'left', 'up'])  # 用于状态周期性的切换
    movemap = {
        'right': (1, 0),
        'down': (0, 1),
        'left': (-1, 0),
        'up': (0, -1),
    }
    # 初始化二维数组
    position_map = dict.fromkeys([(x, y) for x in range(init) for y in range(init)])
    # 初始化当前位置以及当前方向
    positon = (0, 0)
    new_status = next(status)
    for i in range(4*init+1, init * (init+4) + 1):
        old_positon = positon
        # print(list( zip(positon, movemap[new_status])))
        # print('22')
        # print(list(map(sum, zip(positon, movemap[new_status]))))

        # 根据状态进行移动
        positon = tuple(map(sum, zip(positon, movemap[new_status])))
        # 如果超过范围或者碰到已经有值的位置则切换方向
        if (positon not in position_map) or (position_map[positon]):
            new_status = next(status)

            positon = tuple(map(sum, zip(old_positon, movemap[new_status])))

        position_map[old_positon] = i



    # 构造输出信息
    print("When:init = {}".format(init))

    # 打印第一行
    for i in range(1, init+1):
        if i < init:
            print("{}".format(i), end='\t')
        else:
            print("{}".format(i))

    # 构造中心螺旋结构
    for i in range(init):
        print("{}".format(4 * init - i), end='\t')
        for j in range(init):

            print((str(position_map[(j, i)])), end='\t')
        print("{}".format(i + init + 1))

    # 添加最后一行
    for i in range(init*3, init*2, -1):
        # 打印第一行
        print("{}".format(i), end='\t')
        if i == init:
            print("{}".format(i))


if __name__ == "__main__":
    # 参数为init值
    spiral(8)

发表于 2018-04-08 12:42:27 回复(2)
鷐头像
//螺旋数组
function spiralArray(num){
    var n=2*num+1;
    //一维数组
    var a=new Array(n);
    //二维数组
    for(var i=0;i<=n-1;i++){
        a[i]=new Array(n);
    }
    //数组的值全部赋值0
    for(var i=0;i<=n-1;i++){
        for(var j=0;j<=n-1;j++){
            a[i][j]=0;
        }
    }
    //中心
    a[num][num]=1;
    //右侧
    function arrR(e){
        for(var k=1;k<=2*i;k++){
         
            a[k+num-i][num+i]=k+a[num-i+1][num+i-1];
        }
    }
    //下方
    function arrD(e){
        for(var k=1;k<=2*i;k++){
         
            a[num+i][num+i-k]=k+a[num+i][num+i];
        }
    }
    //左侧
    function arrL(e){
        for(var k=1;k<=2*i;k++){
         
            a[num+i-k][num-i]=k+a[num+i][num-i];
        }
    }
    //上方
    function arrU(e){
        for(var k=1;k<=2*i;k++){
        
            a[num-i][num-i+k]=k+a[num-i][num-i];
        }
    }
    if(num>=0){
        for(var i=1;i<=num;i++){
         
            arrR(i);
            arrD(i);
            arrL(i);
            arrU(i);
        }
    }
    //输出打印数组
    document.write("<table style='text-align:center;'>")
    for(var i=0;i<=n-1;i++){
        document.write("<tr>")
        for(var j=0;j<=n-1;j++){
            document.write("<td>"+a[i][j]+"</td>");
            
        }
        document.write("</tr>")
    }
    document.write("</table>")
}
发表于 2017-11-21 09:59:11 回复(0)
   int wheni_max = 0, wheni_min = 0, whenj_max = 0, whenj_min=0;
        private void when()
        {
            int i = 1;
            int N = 0;
            N = 2 + i;//阶乘数量
            int value = 0;//填入值
            int whilecount = 0;//4轮方向循环次数
            wheni_max = N-1;
            whenj_max = N-1;
            int when_index_i=0,when_index_j=0;
            int highx = N * N;//最大循环次数
            int highx_bool = 0;//最大循环中止判断符
            int max_min=0;//执行次数
            int whileN = N;//阶乘数量变换
            int move = 0;//0右移 1 下移 2左移 3上移
            int[,] noresult = { {0, N - 2 }, { 0,N - 1 }, { N - 1, N - 2 }, { N - 1, N - 1 } };//确定不输出的位置
            int[,] result = new int[N, N];//确定输出格式
            while (highx > highx_bool)
            {
                //每处理一次降低2个阶*数量
                //计算公式    5!=4 12   ***** 6!=1 8 16  **** 4!=8
                if ((4 * whileN - 8) == max_min && max_min != 0)
                {
                    wheni_max--;
                    whenj_max--;
                    wheni_min++;
                    whenj_min++;
                    max_min = 0;
                    whileN = whileN - 2;
                }
                //if (whilecount % 3 == 0 && whilecount != 0)
                //{
                    
                //}
                if ((when_index_i == 0 && when_index_j == N - 2) || (when_index_i == 0 && when_index_j == N - 1) || (when_index_i == N - 1 && when_index_j == N - 2) || (when_index_i == N - 1 && when_index_j == N - 1))
                {
                    //result[when_index_i, when_index_j] = value;
                }
                else
                {
                    value++;
                    result[when_index_i, when_index_j] = value;
                }
                    highx_bool++;
                if (move == 0)
                {
                    if (when_index_i == wheni_min && when_index_j < whenj_max)
                    {
                        when_index_j++;
                        if (max_min == 0)
                            max_min = 1;
                        else
                            max_min++;
                    }
                    else
                    {
                        move = 1;
                        when_index_i++;//坐标下移一位
                        whilecount++;//完成一轮循环
                    }
         
                }
                else if (move == 1)
                {
                    if (when_index_j == whenj_max && when_index_i < wheni_max)
                    {
                        when_index_i++;
                        if (max_min == 0)
                            max_min = 1;
                        else
                            max_min++;
                    }
                    else
                    {
                        move = 2;
                        when_index_j--;//坐标左移一位
                        whilecount++;
                    }
                 
                }

                else if (move == 2)
                {
                    if (when_index_i == wheni_max && when_index_j > whenj_min)
                    {
                        when_index_j--;
                        if (max_min == 0)
                            max_min = 1;
                        else
                            max_min++;
                    }
                    else
                    {
                        move = 3;
                        when_index_i--;//坐标上移一位
                        whilecount++;
                    }       
                }
                else if (move == 3)
                {
                    if (when_index_j == whenj_min && when_index_i > wheni_min)
                    {
                        when_index_i--;
                        if (max_min == 0)
                            max_min = 1;
                        else
                            max_min++;
                    }
                    else
                    {
                        move = 0;
                        when_index_j++;//坐标右移一位
                        whilecount++;
                    }
                }
            }
        }
发表于 2017-08-24 10:53:00 回复(4)
各位大佬指点一下
发表于 2018-11-08 23:12:17 回复(0)
首先确定,数列的行数(i+3)和元素个数((i+2)*(i+1)),
发表于 2018-08-14 14:19:42 回复(0)
python实现 https://blog.csdn.net/in_nocence/article/details/80309930
发表于 2018-05-17 19:18:49 回复(0)
public class LargeVolume {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入i(i>0):");
        int i = scanner.nextInt();
        System.out.printf("when i=%d:%n", i);

        // 生成大大卷数组
        int[][] array = generate(i);
        int size = array.length;

        // 数组按要求输出
        for (int a = 0; a < size; a++) {
            for (int b = 0; b < size; b++) {
                // 应该为空格的位置不输出
                if (!((a == 0 || a == size - 1) && (b == size - 1|| b == size - 2))) {
                    // 最后一竖排对原来的数-2
                    if ((a != 0 || a != size - 1) && b == size - 1) {
                        System.out.printf("%d ", array[a][b] - 2);
                        // 第一行不变
                    } else if(a == 0 && (b != size - 1 || b != size - 2)) {
                        System.out.printf("%d ", array[a][b]);
                        // 其他位置数据-4
                    } else {
                        System.out.printf("%d ", array[a][b] - 4);
                    }
                }
                // 转行
                if (b == size - 1) {
                    System.out.println();
                }
            }
        }
    }
    // 生成一个大大卷
    public static int[][] generate(int i) {
        int size = i + 2;
        int[][] array = new int[size][size];
        int length = size / 2;
        int value = 1;
        // 外圈到内圈
        for (int j = 0; j < length; j++) {
            // 一圈
            for (int x = j; x < size - j; x++) {
                array[j][x] = value++;
            }
            for (int y = j + 1; y < size - j; y++) {
                array[y][size - 1 - j] = value++;
            }
            for (int z = size - 2 - j; z >= j; z--) {
                array[size - 1 - j][z] = value++;
            }
            for (int w = size - 2 - j; w > j; w--) {
                array[w][j] = value++;
            }
        }
        // 中间点
        if (size % 2 != 0) {
            array[length][length] = value;
        }
        return array;
    }
}
发表于 2018-04-12 15:59:13 回复(0)
逻辑
发表于 2018-01-05 21:35:44 回复(0)
public class PrintFomateNum1 {
    public static void main(String[] args) {
        printFormateLuoXuan(4);
    }
    /**
     * 螺旋数列
     * 回字数列
     * */
    /**分析的基本规律如下:
     * when i = 4  ; return :
     *1   2   3   4
     *16  17  18  19  20   5
     *15  28  29  30  21   6
     *14  27  32  31  22   7
     *13  26  25  24  23   8
     *12  11  10   9
        ******************************************************************************************************   *实现规则分析:   ******************************************************************************************************
     * 1、第一行和最后一行的个数为i,特殊处理;
     * 第一行的值是:1~i;
     *最后一行值是:3*i ~3*i-(i-1);
     * 2、第一列和最后一列的个数为i-2,特殊处理;
     *第一列的值:4 * i - (r - 1);r表示行数,r<=i;
     *最后一列的值:i+r;r表示行数,r<=i;
     * 3、中间剩余部分是一个i*i的数列,数列的特性如下:
     *a、这个数列的构成是:
     *由外层向内层是由一层层的(i-2*(t-1))*(i-2*(t-1))的口字环构成的;t表示层数,t<=(i+1)/2;
     *b、每层的口字环的四条边的索引和值如下:
     *-----------------------------------------------------------------------------------------------------
     *                  索引  初始值          运算值
     *左上角:upNum | [t][t+c]  | 4*i+1  | upNum(上一次的upNum) + 4*((i-2*t)-1)
     *右上角:riNum | [t+c][t+(i-2*t)-1]  | upNum + i-1 | upNum + i -2*(t+1)-1
     *右下角:doNum | [t+(i-2*t)-1][t+(i-2*t)-1-c] | riNum + i-1 | riNum + i -2*(t+1)-1
     *左下角:leNum | [t+(i-2*t)-1]-c][t] | doNum + i-1 | doNum + i -2*(t+1)-1
     *-----------------------------------------------------------------------------------------------------
     */
    public static void printFormateLuoXuan(int i) {
            //creat i*i array
        printLXArray(i);
        //print first line
        for (int fl = 1;fl<=i;fl++){
            System.out.printf("%4d",fl);
            if (fl == i){
                System.out.println();
            }
        }
        //print other lines
        //rows
        for (int r=1;r<=i;r++){
            //first columns
            for (int cl=1;cl<=i+2;cl++){
                if (cl == 1) {//print first number
                    System.out.printf("%4d",4 * i - (r - 1));
                }
            }
            //other columns i*i list
            for (int e:res[r-1]){
                System.out.printf("%4d",e);
            }
            //last columns
            for (int cl1=1;cl1<=i+2;cl1++){
                if(cl1 == i+2){//print last number
                    System.out.printf("%4d\n",i+r);
                }
            }
        }
        //print last line
        for (int fl = i;fl>=1;fl--){
            System.out.printf("%4d",3*i-(i-fl));
            if (fl == 1){
                System.out.println();
            }
        }
    }
      //i*i array for result
    static int[][] res ;
    public static void printLXArray(int i){
        int upNum = 4*i+1;//upRow fisrt number
        int riNum = upNum + i-1;//rightColumn first number        
            int doNum = riNum + i-1;//downRow first number
        int leNum = doNum + i-1;//leftColumn first number  try{
            res = new int[i][i];
            int rows = (int)(i+1)/2;//总的口字环数
            for (int r=0;r<=rows;r++){
                int con = i - 2*r;//每一个口字环的边长数
                int conu = i -2*(r+1);
                for (int c=0;c<con-1;c++){
                    //print uprow
                    res[r][r+c] = upNum++;
                    //print rightcolumn
                    res[r+c][r+con-1] = riNum++;
                    //print downrow
                    res[r+con-1][r+con-1-c] = doNum++;
                    //print leftcolumn
                    res[r+con-1-c][r] = leNum++;
                }
                upNum = leNum;
                riNum = upNum + conu-1;
                doNum = riNum + conu-1;
                leNum = doNum + conu-1;
                //print res[rows-1][rows-1]
                if (i%2!=0&&r==rows-1){
                              //当i是奇数时输出最后一个口字环的数
                    res[rows-1][rows-1] = 4*i+i*i;
                }
            }
        }catch(Exception ex){
            ex.printStackTrace();
        }
    }
}


//另一种实现方法:
/*与上一个方法(PrintFomateNum1)的主要区别是,将第一行和最后一行以及第一列和最后一列
 *也视为一个合格的口字环进行处理
 */
public class PrintFomateNum2 {
    public static void main(String[] args){
        printFormate(3);
    }

    /**
     * @function print number list
     *             when i = 1
     * @return
     *             1
     *             4 5 2
     *             3
     *             when i = 2
     * @return
     *             1 2
     *             8 9 10 3
     *             7 12 11 4
     *             6 5
     *             when i = 1
     * @return
     *              1   2   3
     *             12  13  14  15   4
     *             11  20  21  16   5
     *             10  19  18  17   6
     *              9   8   7
     * */
    /**
     * 螺旋数列
     * 回字数列
     */
    /*分析的基本规律如下:
     * when i = 4  ; return :
     *1   2   3   4
     *16  17  18  19  20   5
     *15  28  29  30  21   6
     *14  27  32  31  22   7
     *13  26  25  24  23   8
     *12  11  10   9
     *******************************************************************************************************
     * 实现规则:
     *******************************************************************************************************
     *1、将数列理解为一个(i+2)*(i+2)的数列;
     *2、将数列理解为是一个类似“回”字由内外嵌套的两个“口”字组成的结构,
     *该数列是由(int)(((i+2)+1)/2)个“口”字形状逐层嵌套组成;
     *3、最外层的“口”字比较特殊需要单独处理;
     *4、最外层之外的“口”字处理:
     *------------------------------------------------------------------------------------------------------
     *每层四个顶角的索引与值
     *------------------------------------------------------------------------------------------------------
     *                               索引                         初始值                    运算值
     *------------------------------------------------------------------------------------------------------
     *左上角:upNum | [t][t+c]  | 4*i+1  | leNum(last)
     *右上角:riNum | [t+c][t+(i-2*t)-1]  | upNum + i-1  | upNum + i -2*(t+1)-1
     *右下角:doNum | [t+(i-2*t)-1][t+(i-2*t)-1-c]  | riNum + i-1  | riNum + i -2*(t+1)-1
     *左下角:leNum | [t+(i-2*t)-1]-c][t]  | doNum + i-1  | doNum + i -2*(t+1)-1
     *------------------------------------------------------------------------------------------------------
     *5、“口”字形状进行分层处理,每层只处理一个“口”形状的内容(也就是在正方形的四条边上的数);
     *6、每个“口”字处理时按上、右、下、左的顺序依次分别处理每一边的数,每一边只打印(i - 2 * (r-1)-1)个数
     *7、输出打印时对四个空白位置进行特殊处理
     */
    // result array
    static int[][] res;
    public static void printFormate(int i) {
        int upNum = 1;//upRow fisrt number
        int riNum = upNum + i+2 - 2;//rightColumn first number
        int doNum = riNum + i - 1;//downRow first number
        int leNum = doNum + i+2 - 2;//leftColumn first number
            res = new int[i+2][i+2];
            int rows = (int) (i+2 + 1) / 2;//总的口字环数
            for (int r = 0; r <= rows; r++) {
                if (r==0){//print first 口字环
                   for (int c = 0;c<i+1;c++){
                       //print uprow
                       if (c != i+2-2){
                           res[r][c] = upNum++;
                       }
                       //print rightcolumn
                       if (r + c +1!=i+2-1) {
                           res[r + c +1][r + i + 2 - 1] = riNum++;
                       }
                       //print downrow
                       if (r + i + 2 - 1 - c != i+2-2) {
                           res[r + i + 2 - 1][r + i + 2 - 1 - c] = doNum++;
                       }
                       //print leftcolumn
                       res[r + i+2 - 1 - c][r] = leNum++;
                   }
                   //重置右下角数为0
                   res[i+2-1][i+2-1] = 0;
                   upNum = leNum;
                   riNum = upNum + i - 1;
                   doNum = riNum + i - 1;
                   leNum = doNum + i - 1;
                }else {//print other 口字环
                    int con = i - 2 * (r-1);//每一个口字环的边长数
                    int conu = i - 2 * ((r-1) + 1);//上一个口字环的边打印的数
                    for (int c = 0; c < con - 1; c++) {
                        //print uprow
                        res[r][r + c] = upNum++;
                        //print rightcolumn
                        res[r + c][r + con - 1] = riNum++;
                        //print downrow
                        res[r + con - 1][r + con - 1 - c] = doNum++;
                        //print leftcolumn
                        res[r + con - 1 - c][r] = leNum++;
                    }
                    upNum = leNum;
                    riNum = upNum + conu - 1;
                    doNum = riNum + conu - 1;
                    leNum = doNum + conu - 1;
                    //print res[rows-1][rows-1]
                    if (i % 2 != 0 && r == rows - 1) {
                        //当i是奇数时输出最后一个口字环的数
                        res[rows - 1][rows - 1] = 4 * i + i * i;
                    }
                }
            }
         //print result array
         for (int r=0;r<i+2;r++){
             for (int c=0;c<i+2;c++){
                if (!((r==0&&c==i)||(r==i+1&&c==i))){
                    //满足条件时打印
                    //print other number
                    System.out.printf("%4d", res[r][c]);
                }
             }
             //输出换行
             System.out.println();
         }
    }
}

编辑于 2018-01-08 23:05:57 回复(1)
数学模型:从外层开始呈螺旋状往里按照自然数1 2 3…开始数
发表于 2017-12-28 18:02:13 回复(0)
曾经在数学上探讨过这个问题,当时算了几天,有点思路了,然后我深挖就算不出来了,之后变放弃了!没想到会在java中再次相遇!难缘啊
发表于 2017-12-28 12:59:15 回复(0)
dazzling beauty
发表于 2017-12-23 01:21:01 回复(0)
这题有人说下解题思路吗
发表于 2017-12-09 22:47:35 回复(0)
pubulic
发表于 2017-11-08 19:17:14 回复(0)
1
发表于 2017-09-29 12:25:14 回复(0)