水面下の夢

競プロやイラストに興味があります.メインブログがここ.ソシャゲの話はこっち(http://ameblo.jp/0n0-yumechi/).ブログアイコンはYaQ(@8_9_00)さんから.

ABC 028 に参加しました

朗報です!
ABCとはいえ,初めて4問完答達成しました!! やった〜〜〜
125位でした.(私は5^3というこの数字が非常に好きです)

f:id:kawasumi_yume:20150829230359p:plain

A問題

A: テスト評価 - AtCoder Beginner Contest 028 | AtCoder

点数を見て分岐.本当に授業でやるようなレベルの問題だった…

n = int(input())
if n < 60:
    print("Bad")
elif 60 <= n < 90:
    print("Good")
elif 90 <= n < 100:
    print("Great")
else:
    print("Perfect")

B問題

B: 文字数カウント - AtCoder Beginner Contest 028 | AtCoder

本当はdictionaryでやれば良いと思ったのだが,OrderedDictionaryじゃないと順序が維持されないので,失敗.(これで2WAして順位を大きく下げた)
別の方法として,アスキーコード変換して,入力された文字を利用してインデックスを決定,そして入れるような形にする.
Dictionaryでうまく行かず,すぐにこちらに書き換えたが,少し時間がかかりすぎてしまった.

li = [0 for _ in range(6)]
for c in input():
	li[ord(c) - ord('A')] += 1
print(" ".join(map(str, li)))

C問題

C: 数を3つ選ぶマン - AtCoder Beginner Contest 028 | AtCoder

DPみたいにすればいいのかなーと思い,現在の値とこれまで足した数字の回数をリストに入れて処理.
これまでの合計値である各数に対して,まだ足せるならば足していくみたいな感じ.

最後に集計されたデータを降順ソートし,3番目のデータを取り出す….
結果的に一発で通った.

入力される数字の数が多くなった場合,Pythonだと落ちそうな気がしないでもない….

ちなみに以前の私なら結構苦戦したと思うので,簡単なDPを練習しておいてよかった.

elems = list(map(int, input().split()))
# 追記:昇順なのでソートいらない^^;
# elems.sort()

# 足しあわせ
table  = [[elems[0], 1], [0, 0]]
for i in range(1, 5):
	for j in range(len(table)):
		if table[j][1] < 3:
			table.append([table[j][0] + elems[i], table[j][1] + 1])
# 重複データ削除
li = set([])
for i in range(len(table)):
	if table[i][1] == 3:
		li.update(set([table[i][0]]))
li = list(li)

# ソートして出力
li.sort(reverse=True)
print(li[2])

追記:公式の解説を読めばわかるけど,三番目になる可能性があるのは二通りなので,そのmax取ればいいらしい… ダメダメですわ^^;

追々記:ソースコードも追加.
Submission #483499 - AtCoder Beginner Contest 028 | AtCoder

a, b, c, d, e = map(int, input().split())
print(max(a+d+e, b+c+e))

D問題

D: 乱数生成 - AtCoder Beginner Contest 028 | AtCoder

立式する.僕は手書きで立式してた.これは考えているところの一部.

数学系のやつは考えるのが苦手なので,紙に書きながら頑張って式変形するほうが良いと思う.
(なのでコンテスト中に急にノートをとりにかばんに走った)

結果から言えば,

  • m, m, m と m, m, hogehogeは任意)とm, lower_m, higher_m(lower_mはm未満の数,higher_mはmより大きい数)が該当するので,1 + (n - 1) * 3 * *1 * 6 という式になる

入力例1を必死にトレースすると,m, m, hogeの場合は並べ方が3通り,lower_m, m, higher_m の場合は6 通り(3! 通りだと思う,数学は忘れているので自信無し)の並べ方があるとわかる.m, m, mは並べ方1通りなのは大丈夫ですよね….
なので,これを出力してやればOK.

n,k = map(int, input().split())
upi = 1 + (n - 1) * 3 + ((k - 1) * (n - k)) * 6
print(upi / (n ** 3))


数学頑張ればいいD問題より,C問題のほうがプログラムチックだなあと思いました(小並感)
とにかく今回は完答で来て良かったです.

追記:
公式の解説読むと自分のコードがいかにボロボロかわかるな^^;

*1:k - 1) * (n - k