問題:
從鍵盤讀入一個數,列印出以下特點的矩陣,
如輸入3,則輸出為:
1 2 3
8 9 4
7 6 5
若輸入4,則輸出為:
1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7
顯然,該問題應用陣列來存盤資料,所以重點是找出賦值的規律,從問題中能夠看出,矩陣是按順時針順序,從外圈到內圈,由1到n逐個賦值,且每行(列)都為n個數,
想法
以一個6*6的回行矩陣為例,將每個數視為一個點,按照順序依次連接,得到一個“回行迷宮”,按照其規律,我們就是要沿著迷宮墻壁(即圖示連線)走,每走一步,賦一個值,走到一定步數后就90°轉向換個方向繼續走,

Question:
那么,要走多少步呢?這個步長是否也有規律可循?還有,轉向時的方向該如何判斷?...
仔細揣摩,發現矩陣走完每一面墻壁的步長依次是5、5、5、4、4、3、3、2、2、1、1,走完一個步長即轉向,且只有上、下、左、右四個方向,
若拋開第一面墻壁,則剩余的墻壁中,每兩個墻壁具有相同的長度,且互相垂直,同時每走完兩面墻壁,步長減1,故考慮第一面墻壁單獨處理,剩余墻壁按相同規則處理,

試著連接副對角線上的數,則可得到5個從大到小、以虛線為底邊的等腰直角三角形(暫且不管第一行),且5個等腰直角三角形的腰長依次為5、4、3、2、1 (接下來我們就以一個三角形為基準來執行操作),
先將第一行單獨賦值,然后就是走出5個等腰直角三角形,
站在小人位置,第一個三角形腰長為5(初始方向向下),接著每走完一個腰長就90°轉向,每走完兩個腰長(即走出一個等腰直角三角形),將腰長-1,
轉向周期為4,按照向下、向左、向上、向右的順序,以此往復,

總結
- 對于一個n*n的回行矩陣,將其每個數視為一個點,按賦值順序依次連接起來;
- 連接副對角線上的點,則可得到
n-1個等腰直角三角形以及額外的一條直線 (即第一行); 這n-1個等腰直角三角形的腰長逐個遞減1; - 第一行單獨賦值,走三角形時的初始方向為向下,步長為
n-1,走完一個步長轉向,走完兩個步長除了轉向還要將步長減1; - 回圈條件為
while(a[i][j] != n*n),方向用四個數字表示,可通過方向變數的值來控制方向變化,
代碼實作
public class NumberOfRounds {
private static final int DOWN = 0; //向下
private static final int LEFT = 1; //向左
private static final int UP = 2; //向上
private static final int RIGHT = 3; //向右
public static void main(String [] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Please input num:");
int n;
n = sc.nextInt();
int[][] roundsNum = new int[n][n];
int number=1;
int i=0,j=0;
//先單獨處理第一行
while(i==0&&j<n) {
roundsNum[i][j] = number++;
j++;
}
j--;
int direction = 0;
int step = n-1;
int currentStep=0;
while(roundsNum[i][j]!=n*n) {
switch(direction%4){
case DOWN:
i++;
break;
case LEFT:
j--;
break;
case UP:
i--;
break;
case RIGHT:
j++;
break;
}
roundsNum[i][j] = number++;
currentStep++;
if(currentStep % step == 0) {
direction++;
//走完一個等腰三角形,則將當前已走步數清0,并將步長減1
if(currentStep == step*2) {
step--;
currentStep=0;
}
}
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/256193.html
標籤:其他
上一篇:MongoDB:原來我如此簡單
下一篇:C/C++基礎知識:變數的作用域
