天天看點

列印十字圖

問題描述
小明為某機構設計了一個十字型的徽标,如下所示:

..$$$$$$$$$$$$$..
..$...........$..
$$$.$$$$$$$$$.$$$
$...$.......$...$
$.$$$.$$$$$.$$$.$
$.$...$...$...$.$
$.$.$$$.$.$$$.$.$
$.$.$...$...$.$.$
$.$.$.$$$$$.$.$.$
$.$.$...$...$.$.$
$.$.$$$.$.$$$.$.$
$.$...$...$...$.$
$.$$$.$$$$$.$$$.$
$...$.......$...$
$$$.$$$$$$$$$.$$$
..$...........$..
..$$$$$$$$$$$$$..

對方同時也需要在電腦dos視窗中以字元的形式輸出該标志,并能任意控制層數。 

輸入格式
一個正整數 n (n < 30) ,表示要求列印圖形的層數
輸出格式
對應包圍層數的該标志

樣例輸入
1
樣例輸出
..$$$$$..
..$...$..
$$$.$.$$$
$...$...$
$.$$$$$.$
$...$...$
$$$.$.$$$
..$...$..
..$$$$$..

      

題目分析:

把題目的圖形變形一下就可以很清楚地看到十字了

列印十字圖

(1)當 n = 1 時 (為了讓這個圖更加直覺,重新畫了這個圖)

列印十字圖

中間十字的位置是固定的,它的坐标是(N / 2 + 1, N / 2 + 1)

假設當圖像的規格為 N*N ,且儲存在二維數組中的橫坐标均從1開始

那麼列印中間黃色十字架的代碼為

for (int i = N/2 -1; i <= N/2 + 3; i++) {
cross[N/2 + 1][i] = cross[i][N/2 + 1] = $;
        }
      

2.當 n = 2 時,觀察黃色部分

列印十字圖

假設從最外面的層數到最裡面的層數分别為 1 , 2 , 3 , …… ,n-3 , n-2 , n-1 , n(圖像規格 N* N)

假設目前為第 i 層,那第 i 層的四個黃色部分邊角坐标與 i 和 N 的關系如下:

(1)左上角的邊角(格子1)坐标為(x ,y), x = 2 i + 1 , y = 2 i + 1

格子1 上面的格子左邊(x - 1 , y), 格子1 左面的格子左邊(x , y - 1)

(2)右上角的邊角(格子2)坐标為(x ,y), x = 2 i + 1 , y = N - 2 i

格子2 上面的格子左邊(x - 1 , y), 格子1 左面的格子左邊(x , y +1)

(3)右上角的邊角(格子3)坐标為(x ,y), x = N - 2 i , y = N - 2 i

格子3 上面的格子左邊(x + 1 , y), 格子1 左面的格子左邊(x , y +1)

(4)右上角的邊角(格子4)坐标為(x ,y), x = N - 2 i , y = 2 i + 1

格子4 上面的格子左邊(x + 1 , y), 格子1 左面的格子左邊(x , y - 1)

那麼這四個邊角位置的列印代碼 如下:

for (int i = 1; i <= n; i++) {
int x = 2 * i + 1;
int y = 2 * i + 1;

//左上角
cross[x][y] = cross[x][y-1] = cross[x-1][y] = 1;
//右上角
y = N - 2 * i;
cross[x][y] = cross[x][y+1] = cross[x-1][y] = 1;
//左下角
y = 2 * i  + 1;
cross[x][y] = cross[x][y-1] = cross[x+1][y] = 1;
//右下角
x = N - 2 * i;
cross[x][y] = cross[x][y+1] = cross[x+1][y] = 1;
        }
      

3. 當 n = 3 時,觀察下圖黃色部分

列印十字圖

同樣假設從最外面的層數到最裡面的層數分别為 1 , 2 , 3 , …… ,n-3 , n-2 , n-1 , n(圖像規格 N* N)

最外層4條黃色的邊長度都一樣,都是 N - 4個格子 (層數逐漸往裡時減去的格子數量也逐漸增加)

(1)十字架上方黃色部分

行數:第一層黃色部分的行數是 1 ,第二層黃色部分的行數是 3 ,第一層黃色部分的行數是 5 ,即十字架上方黃色部分的行數随着層數的增加其變化規律是: 2* i - 1 (i 為目前十字架的層數)

列數:起點坐标:2* i + 1,終點坐标 :N - 2* i

列印十字架上方黃色部分的代碼

for (int i = 1; i <= n; i++) {
for (int j = 2*i + 1; j <= N - 2*i ; j++) {
corss[2*i - 1][j] = 1;
            }
        }
      

(2)十字架右方黃色部分

行數:起點坐标 2* i + 1 , 終點坐标 N - 2* i

列數:第一層列數 N ,第二層 N - 2,第三層 N - 4,變化規律:N - 2 * (i - 1)

for (int i = 1; i <= n; i++) {
for (int j = 2*i - 1; j <= N - 2*i ; j++) {
cross[j][N - 2*(i - 1)] = 1;
            }
        }
      

(3)十字架下方黃色部分

行數:第一層列數 N ,第二層 N - 2,第三層 N - 4,變化規律:N - 2 * (i - 1)

列數:起點坐标 2* i + 1 , 終點坐标 N - 2* i

for (int i = 1; i <= n; i++) {
for (int j = 2*i + 1; j <= N - 2*i ; j++) {
cross[N - 2*(i - 1)][j] = 1;
            }
        }
      

(4)十字架左方黃色部分

列數:第一層黃色部分的行數是 1 ,第二層黃色部分的行數是 3 ,第一層黃色部分的行數是 5 ,即十字架上方黃色部分的行數随着層數的增加其變化規律是: 2* i - 1

for (int i = 1; i <= n; i++) {
for (int j = 2*i + 1; j <= N - 2*i ; j++) {
corss[j][2*i - 1] = 1;
            }
        }
      

行列變化時,外層條件一緻

把行列變化放到一個循壞體中

for (int i = 1; i <= n; i++) {
for (int j = 2*i + 1; j < N - 2*i; j++) {
cross[2*i -1][j] = cross[j][N - 2*(i - 1)] 
= cross[N - 2*(i - 1)][j] = cross[j][2*i - 1] = true;
            }
        }
      

完整代碼

import java.util.Scanner;

public class PrintCrossGraphics {
final int MAX = 130;
boolean[][] cross = new boolean[MAX][MAX];

public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);

int n = scanner.nextInt();
PrintCrossGraphics print = new PrintCrossGraphics();
print.PrintCross(n);

    }

//列印十字圖形
public  void PrintCross(int n){
int N = 5 + 4 * n; //通過n計算列印圖形的規格(N * N)

//中間十字架
for (int i = N/2 -1; i <= N/2 + 3; i++) {
cross[N/2 + 1][i] = cross[i][N/2 + 1] = true;
        }

//四個邊角
for (int i = 1; i <= n; i++) {

int x = 2 * i + 1;
int y = 2 * i + 1;
//左上角
cross[x][y] = cross[x][y-1] = cross[x-1][y] = true;
//右上角
y = N - 2 * i;
cross[x][y] = cross[x][y+1] = cross[x-1][y] = true;
//右下角
x = N - 2 * i;
cross[x][y] = cross[x][y+1] = cross[x+1][y] = true;
//左下角
y = 2 * i  + 1;
cross[x][y] = cross[x][y-1] = cross[x+1][y] = true;


//行列變化的循壞體
for (int j = 2*i + 1; j <= N - 2*i; j++) {
cross[2*i -1][j] = cross[j][N - 2*(i - 1)] =
cross[N - 2*(i - 1)][j] = cross[j][2*i - 1] = true;
                }

        }

//列印
for (int i = 1; i <= N ; i++) {
for (int j = 1; j <= N; j++) {
if (cross[i][j]  )
System.out.print("$");
else
System.out.print(".");
            }
System.out.print("\n");
        }
    }
}

      

運作結果

列印十字圖
列印十字圖