问题描述
图片说明

> 第一种解法:依次完成上下左右
> While(执行n/2向上取整次){
>         Up(arr,row,from,to,num);       
>          完成上面一行,row行 从form到to,
>         Right(arr,col,from,to,num);
>         完成右边一列,col列 从from到to,     
>         Down(arr,row,from,to,num);   
>         完成下边一行,row行 从to回到from
>         Left(arr,col,from,to,num);        
>         完成左边一列,col列 从to回到from
> }

图片说明

第二种算法:直接用算法找规律
将矩阵分为4大块:
上【红】下【蓝】左【绿】右【黑】
上:行数<=n/2向上取整
                判断一下是否在列的取值范围:
                行数row,m+1-row
下:行数>n/2

例如说:20行22列
给定第一个数:5行6列,只需要找到起始的位置273,根据第六列可以算出276
给定第二个数:15行8列,先找到对应的圈数:20-15+1=6,起始位置361,算出根据第8列可算出350
给定第三个数:15行1列,找到圈数算出80,根据行数15可算出67
给定第四个数:15行22列,找到圈数算出22,根据行数15算出36

图片说明

实例代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class G {
    public static void main(String[] args) {
        try {

            //1、输入四个数据m、n、row、col
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            String str = null;
            str = br.readLine();
            String[] values = str.split(" ");
            int n = Integer.parseInt(values[0]);
            int m = Integer.parseInt(values[1]);
            str = br.readLine();
            values = str.split(" ");
            int row = Integer.parseInt(values[0]);
            int col = Integer.parseInt(values[1]);
            //方法1:
            System.out.println("方法1矩阵:");
            long start1 = System.currentTimeMillis();
            fun2(n,m,row,col);
            long end1 = System.currentTimeMillis();
            System.out.println("方法1执行时间"+(end1-start1)+"ms");

            System.out.println("---------------------------------------------");
            //方法2:
            System.out.print("方法2查询结果:");
            long start2 = System.currentTimeMillis();
            fun(n,m,row,col);
            long end2 = System.currentTimeMillis();
            System.out.println();
            System.out.println("方法2执行时间:"+(end2-start2)+"ms");
            System.out.println("方法2矩阵:");
            for (int i = 1; i <= n; i++) {
                for (int j = 1; j <= m; j++) {
                    fun(n,m,i,j);
                }
                System.out.println();
            }
            //2、计算值

        } catch (IOException e) {
            e.printStackTrace();
        }

    }
        public static void fun(int n,int m,int row,int col) {
            try {
                if(row<=n/2+(n%2==0?0:1) && col>=row&&col<=m+1-row){//1 - m     2 - m-1
                // 上
                    int pos_up = getPos_up(n, m, row, col);
                    System.out.print(pos_up+"\t");
                }else if (row>n/2+(n%2==0?0:1) && col>=n+1-row&&col<=m-n+row){
                // 下
                    int pos_down = getPos_down(n, m, row, col);
                    System.out.print(pos_down+"\t");
                }else if(col<=m/2+(m%2==0?0:1)){
                // 左
                    int pos_left = getPos_left(n, m, row, col);
                    System.out.print(pos_left+"\t");
                }else{
                // 右
                    int pos_right = getPos_right(n, m, row, col);
                    System.out.print(pos_right+"\t");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    public static int getPos_up(int n,int m,int row,int col){//20行20列 5行6列
        int quan = row;//行数即圈数
        int s=0;
        int time = 0;
        int M = m;
        while(time<quan-1){
            s+=(M+n)*2-4;
            M-=2;n-=2;
            time++;
        }
        s=s+col-quan+1;
        return s;
    }
    public static int getPos_left(int n,int m,int row,int col){
        int quan = col;
        int s=0;
        int time = 0;
        int M = m;
        while(time<=quan-1){
            s+=(M+n)*2-4;
            M-=2;n-=2;
            time++;
        }
        s-=(row-1-quan);
        return s;
    }
    public static int getPos_right(int n,int m,int row,int col){
        int quan = m + 1 - col;
        int s=0;
        int time = 0;
        int M = m;
        while(time<quan-1){
            s+=(M+n)*2-4;
            M-=2;n-=2;
            time++;
        }
        s+=(m-(quan-1)*2);
        s+=(row-quan);
        return s;
    }
    public static int getPos_down(int n,int m,int row,int col) {// 2 5
        int time = 0;
        int s=0;
        int M = m;
        //圈数:
        int quan = n-row+1;//20-19
        while(time<quan-1){
            s+=(M+n)*2-4;
            M-=2;n-=2;
            time++;
        }
        s += (M+n)-2;
        s+=(m+1-col-quan+1);
        return s;
    }



    public static void fun2(int n,int m,int row,int col){
        //1、初始化为0
        int[][] arr= new int[n+1][m+1];
        //2、上下左右
        int num = 1 ;
        for (int i = 1; i <= m/2+(m%2==0?0:1); i++) {//35 37
            // 上
            num = up(arr,i,i,m+1-i,num);//  10 10,22
            // 下
            num = right(arr,m+1-i,i+1,n-i,num);
            // 左
            num = down(arr,n+1-i,m+1-i,i,num);
            // 右
            num = left(arr,i,n-i,i+1,num);
        }
        display(arr);
        System.out.println("方法1查询结果:"+arr[row][col]);
    }

    private static int left(int[][] arr, int c, int to, int from,int num) {
        for (int i = to; i >= from ; i--) {
            if(arr[i][c]==0)arr[i][c]=num++;
        }
        return num;
    }

    private static int down(int[][] arr, int r, int to, int from, int num) {
        for (int i = to; i >= from; i--) {
            if(arr[r][i]==0)arr[r][i]=num++;
        }
        return num;
    }

    private static int right(int[][] arr, int c, int from, int to, int num) {
        for (int index = from; index <= to; index++) {
            if(arr[index][c]==0)arr[index][c]=num++;
        }
        return num;
    }

    private static void display(int[][] arr) {
        for (int i = 1; i < arr.length; i++) {
            for (int j = 1; j < arr[0].length; j++) {
                System.out.print(arr[i][j]+"\t");
            }
            System.out.println();
        }
    }

    public static int up(int[][] arr,int r,int from,int to,int num){
        for (int i = from; i <= to; i++) {
            if(arr[r][i]==0)arr[r][i] = num++;
        }
        return num;
    }
}

图片说明
图片说明
图片说明
图片说明