註釋“PAT 乙級 1027. 列印沙漏(20) Java版”——讓你輕鬆讀懂
阿新 • • 發佈:2018-11-08
尊重原作者,原文資訊如下。
原文作者:柳婼
來源: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是怎麼算出來的,提示一下,用等差數列公式。
幫到你的話點個贊奧,嘿嘿!!!