1. ホーム
  2. スクリプト・コラム
  3. ゴラン

初心者のための囲碁言語 ブラッシュアップ プリントアウト砂時計

2022-01-09 14:41:29

問題解決

[PTAグループ プログラミングラダー】 L1-002 砂時計のプリント(20点) Go|Golang

この問題は、与えられた記号を砂時計の形に印刷するプログラムを書かせるものである。例えば、17個の"*"が与えられた場合、以下のような形式で印刷するように求められます。

<ブロッククオート

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

砂時計型とは、各行が奇数個の記号を出力し、各行が中央にあり、隣接する2行の記号の数が2個異なり、記号の数が最大から最小、1へと減少し、最小から最大へと増加し、最初と最後の記号の数が同じであることを意味します。

任意のN個の記号があるとき、それらが正確に1個の砂時計を形成する必要はない。砂時計は、できるだけ多くの記号を使い切るように印刷されなければならない。

入力フォーマット。

入力は1行に1個の正の整数N(≦1000)と記号をスペースで区切って与える。

出力形式です。

まず与えられた記号からなる最大の砂時計の形を出力し、最後に残りの未使用記号の数を1行で出力せよ。

入力サンプルです。

19 *

末尾に空白行がないこと

出力例です。

<ブロッククオート

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

末尾に空白行がない

アイデア

基本的なアウトプットは、この問題が不親切だと感じたら、読み飛ばして、後で戻って理解することができます。

パターンを見つけて、まずいくつ必要かを計算することです。次にそれを引いて残りの数を出します。そして、そのパターンに従って砂時計を印刷する。これは、実は等変数系列である。

以下はそのコードです。

package main
import (
	"fmt"
)
func main() {
	var n int
	var tag byte
	var sum, nextSum int
	_, _ = fmt.Scanf("%d %c", &n, &tag)
	sum = 1
	nextSum = 1
	i := 1
	last := 0
	for true { // first calculate how many symbols are needed
		i += 2
		nextSum += i * 2
		if nextSum <= n {
			sum += i * 2
		} else {
			i -= 2
			last = n - sum
			break
		}
	}
	for j:=i; j>=1; j=j-2 { // print the top half first
		var space = (i - j) / 2
		for k:=0; k<i-space; k++ {
			if k < space {
				fmt.Printf(" ") // print space first
			} else {
				fmt.Printf("%c", tag) // print * again
			}
		}
		fmt.Println() // remember to break the line at the end
	}
	for j:=3; j<=i; j=j+2 {
		var space = (i - j) / 2 // then print the bottom half
		for k:=0; k<i-space; k++ {
			if k < space{
				fmt.Printf(" ") // print * again
			} else {
				fmt.Printf("%c", tag)
			}
		}
		fmt.Println()
	}
	fmt.Println(last)
}



以上、Go言語白人の入門筆のプリントアウト砂時計の詳細、Go言語プリントアウト砂時計の詳細については、スクリプトハウスの他の関連記事に注意してください!。