1. 程式人生 > >註釋“PAT 乙級 1027. 列印沙漏(20) Java版”——讓你輕鬆讀懂

註釋“PAT 乙級 1027. 列印沙漏(20) Java版”——讓你輕鬆讀懂

尊重原作者,原文資訊如下。

原文作者:柳婼
來源:CSDN
原文:https://blog.csdn.net/liuchuo/article/details/56676279
版權宣告:本文為博主原創文章,轉載請附上博文連結!

我只是對其程式碼按自己的理解做了註釋,特此強調

剛開始刷PAT,這是第一題,自己寫不出來沙漏(自己太笨——手動捂臉)於是找了一些前人寫的學習。看到這位大神(確實是大神,貌似是一個妹子,拿了很多證書的妹子——自慚形愧啊)!!!
程式碼沒註解,不適合我這種萌新。於是在我花了幾個小時(是的,你沒看錯!花了我幾個小時,再次自慚形愧)參透之後寫下此文,便於大家理解。

本題要求你寫個程式把給定的符號列印成沙漏的形狀。例如給定17個“*”,要求按下列格式列印

 *****
  ***
   *
  ***
 *****

所謂“沙漏形狀”,是指每行輸出奇數個符號;各行符號中心對齊;相鄰兩行符號數差2;符號數先從大到小順序遞減到1,再從小到大順序遞增;首尾符號數相等。

給定任意N個符號,不一定能正好組成一個沙漏。要求打印出的沙漏能用掉儘可能多的符號。

輸入格式:

輸入在一行給出1個正整數N(<=1000)和一個符號,中間以空格分隔。

輸出格式:

首先打印出由給定符號組成的最大的沙漏形狀,最後在一行中輸出剩下沒用掉的符號數。

輸入樣例:

19 *

輸出樣例:

*****
 ***
  *
 ***
*****
2	

大神的程式碼如下,我只在上面以註釋的方式寫下我的理解,如有不足或錯誤,請賜教……

實現程式碼

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		char c = in.next().charAt(0);
		in.close
();//這些不用說了,我相信大家都懂的 //我們設定列印時字元為1所在行的行號為w,找到w和所輸入數字n之間的關係 //通過等差數列求得n=2*w*w-1,所以得出w如下 int w = (int) Math.sqrt((n + 1) / 2); for (int i = 0; i < 2 * w - 1; i++) { for (int j = 0; j < 2 * w - 1; j++) { //此處最難理解,為了便於理解我畫了一張圖放在下邊,請移步 if ((i > j && i + j < 2 * w - 2) || (i < j && i + j > 2 * w - 2)) { //第一遍看的時候以為此處的if多餘,其實是為了效率, //當然去掉也能打印出想要的效果,只是多列印了一些空格 //這一行if不禁讓我感慨自己和大神的差距啊(又一次自慚形愧……) if (i > j && i + j < 2 * w - 2) System.out.print(" "); } else { System.out.print(c); } } //換行 System.out.println(); } //輸出多餘的數的數值 System.out.println(n - 2 * w * w + 1); } }

圖片輔助理解

以5行為例,即w=3,i和j是分別是巢狀迴圈的外、內計數值。
當程式進入else則執行列印對角線和對角線的上下夾角間的白色區域 。黃色區域是進入第二個if。如果不加第二個if,那麼綠色區域會被列印空格,造成不必要的開銷(個人覺得此處的處理很精髓)
在這裡插入圖片描述
好了就是這麼多,還有一點:如果沒看懂n是怎麼算出來的,提示一下,用等差數列公式。
幫到你的話點個贊奧,嘿嘿!!!