名もなき未知

エンジニアリングとか、日常とかそういうのをまとめる場所。アクセス解析のためGAを利用、Googleに情報を送信しています。商品紹介のためAmazonアフィリエイトを利用、Amazonに情報を送信しています。記事に関しては私が書いていない引用文を除いて自由にご利用ください。

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