印出星星(金字塔)

這是來自 LIOJ 上的題目,因為我居然感到困惑,所以想記錄下來。

找出規律

這一題其實就難在找規律,規律如果找不出來,就會想不出解法。

先試著觀察看看:

1
2
3
  *
***
*****

要找出的規律是「每行有幾個星星」跟「每行有幾個空格」。

先看空格的部分:

  • 第一行有 2 個空白
  • 第二行有 1 個空白
  • 第三行有 0 個空白

這裡假設 n = 全部有幾行,i = 目前的行數,換句話說就是最外層迴圈的次數:

1
2
3
for(let i=1; i<=n; i++) {
...
}

仔細觀察一下可以看出空白的數量跟 n 還有 i 有關,也就是 n-i = 那一行需要的空格數:

  • 第一行有 3-1 個空白
  • 第二行有 3-2 個空白
  • 第三行有 3-3 個空白

所以空格的部分可以這樣處理:

1
2
3
for(let i=1; i<=n; i++) {
repeat(' ', n-i)
}

接著來看星星的部分:

  • 第一行有 1 個星星
  • 第二行有 3 個星星
  • 第三行有 5 個星星

這裡也是我卡住的地方,因為我沒辦法從 ni 之間找出這個規律,也不知道該從哪裡思考,

不過後來想想其實可以用「數學函數」的方式來思考,例如:

f(i) = 對 i 做某個算式 = 輸出值

  • f(1) = 1
  • f(2) = 3
  • f(3) = 5

從這裡可以發現規律是 「每一圈都會增加 2」,也就是說,每一圈都要 x2

1
2
3
4
f(i) = i * 2
f(1) = 2
f(2) = 4
f(3) = 6

做到這裡後應該不難發現,只要再把每一項 -1,就能達成目標:

1
2
3
4
f(i) = i * 2 - 1
f(1) = 1
f(2) = 3
f(3) = 5

所以最後 2i-1 可以完成這個函數,規律就找出來了:

1
2
3
for(let i=1; i<=n; i++) {
repeat('*', i*2-1)
}

最後把整個程式組合一下:

1
2
3
for(let i=1; i<=n; i++) {
console.log(repeat(' ', n-i) + repeat('*', i*2-1))
}

這樣就解完這題了。

最後再考你一題:

1
2
3
f(1) = 0
f(2) = 2
f(3) = 4
想完再來看解答 答案是:f(i) = 2i - 2

紀錄

附上原始程式碼,原本的想法是「建立一個奇數陣列來做 mapping」:

  • 第 1 行會在 createStarts() 代入 1,產出 1 個星星
  • 第 2 行會在 createStarts() 代入 3,產出 3 個星星
  • 第 3 行會在 createStarts() 代入 5,產出 5 個星星
  • 以此類推
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
function solve(lines) {
// 總共有幾行
let n = Number(lines[0])
// 用來儲存奇數的陣列
let arr = []
// 建立陣列(輸入範圍是 1 ~ 30,所以第 30 行會有 59 顆星星)
for(let i=1; i<=60; i++) {
// 只儲存奇數
if(i&1) arr.push(i)
}

// 印出 1 ~ n 行
for(let i=1; i<=n; i++) {
// 儲存最後要印出的內容
let content = ''
// 陣列從 0 開始,所以才得 arr[i-1]
content = createWhiteSpace(n-i) + createStarts(arr[i-1])
console.log(content)
}
}
// 第 i 行會有 n-i 個空白
function createWhiteSpace (n) {
let result = ''
for(let i=0; i<n; i++) {
result += ' '
}
return result
}
// 依照 1, 3, 5 的順序印出星星
function createStarts (n) {
let result = ''
for(let i=0; i<n; i++) {
result += '*'
}
return result
}

求出 1-100 的平方數 The-power-of-habit 讀後紀錄
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×