こんにちは, Shinoryoです.
今回はSOMPO HD プログラミングコンテスト2021(AtCoder Beginner Contest 192)を, Pythonで解いてみた結果を書き連ねていこうと思います.
AtCoder Beginner Contest 192 - AtCoder
AtCoder is a programming contest site for anyone from beginners to experts. We hold weekly programming contests online.
目次[非表示]
A - Star
求めるのは,
# 出力 | |
print(100 - (int(input()) % 100)) |
B - uNrEaDaBlE sTrInG
文字列
文字列の中の文字が大文字か小文字かを判定するには, .islower()や.isupper()を使用します.
.islower()は, 以下の2つの条件がどちらも満たされる場合, Trueを返します. そうでなければFalseを返します.
- 文字列中に大文字と小文字の区別のある文字が1文字以上存在する.
- その大文字と小文字の区別のある文字の全てが小文字である.
.isupper()は, 以下の2つの条件がどちらも満たされる場合, Trueを返します. そうでなければFalseを返します.
- 文字列中に大文字と小文字の区別のある文字が1文字以上存在する.
- その大文字と小文字の区別のある文字の全てが大文字である.
偶数番目を取り出した文字列に関する判定には注意が必要です. 文字列
# 入力 | |
S = input() | |
# Sの長さを格納 | |
Slength = len(S) | |
# 奇数番目だけ、偶数番目だけを用意 | |
Seven = "" | |
Sodd = "" | |
for i in range(0, Slength, 2): | |
Seven += S[i] | |
for i in range(1, Slength, 2): | |
Sodd += S[i] | |
# 判定 | |
if Seven.islower() and (Sodd.isupper() or not(Sodd)): | |
print("Yes") | |
else: | |
print("No") |
C - Kaprekar Number
意外にも, 問題文にあることをそのまま実行すれば通ります. 「各桁の数字を大きい順に並び替えて」「各桁の数字を小さい順に並び替えて」には, 整数型を文字列型にして, その各文字を整数型にしてソートすればよいです.
# 整数列Sintlist_funcを入力されて、10進法におけるSintlist_funcの値を出力する関数 | |
def Nshinhou(Sintlist_func): | |
output = 0 | |
for i in Sintlist_func: | |
output = output * 10 + i | |
return output | |
# 整数iを入力されてg_1(i)を出力する関数 | |
def g_1(i): | |
i_descending = sorted([int(x) for x in str(i)], reverse=True) | |
return Nshinhou(i_descending) | |
# 整数iを入力されてg_2(i)を出力する関数 | |
def g_2(i): | |
i_ascending = sorted([int(x) for x in str(i)]) | |
return Nshinhou(i_ascending) | |
# 整数iを入力されてf(i)を出力する関数 | |
def f(i): | |
return g_1(i) - g_2(i) | |
# 入力 | |
N, K = [int(x) for x in input().split()] | |
# 操作 | |
for _ in range(K): | |
N = f(N) | |
# 出力 | |
print(N) |
D - Base n
ここで用いる二分探索の概要
二分探索とは, ソート済みのリストに対する検索を行うにあたって有用なアルゴリズムです.
- ある
とある の値を用意します. と の真ん中の値として をとります. 進法における の値を確認します. 進法における の値が 以下である(つまり, 条件を満たす)ならば, とします(次は, より大きい値を確認します). 進法における の値が より大きい(つまり, 条件を満たさない)ならば, とします(次は, より小さい値を確認します).
と の差が になるまで上の作業を続けます.
このようにして得られた
lowとhighの初期値
二分探索を行うにあたって,
: を採用します. もし 以上の全ての に対して, 進法における の値が より大きい(つまり, 条件を満たさない)場合は となり, 出力される値は となります. : を採用します. 後述するように, が2桁以上の場合(つまり, 以上)に対して二分探索を適用します. すると, 進法における の値は必ず 以上になります. よって, 進法における の値は必ず より大きくなります.
細かい場合の補足
- そもそもが
の場合: 以上の全ての に対して, 進法における の値が より大きくなります. 下のコード例では「while low + 1 < high」として, の場合には二分探索を行わず となるようになっています. が1文字の場合:二分探索は使えないので, 最初に場合分けしておく必要があります.
# 整数列Xintlist_funcと底N_funcを入力されて、N_func進法におけるXintlist_funcの値を出力する関数 | |
def Nshinhou(Xintlist_func, N_func): | |
output = 0 | |
for i in Xintlist_func: | |
output = output * N_func + i | |
return output | |
# 入力 | |
Xintlist = [int(x) for x in input()] | |
M = int(input()) | |
# Xに含まれる最も大きい数字dを求めておく | |
d = max(Xintlist) | |
# Xの文字数が1文字のとき、(d+1以上の)全ての位取り記数法の場合で同じ値が得られる | |
# 2文字以上の場合とは決定的に違うので、場合分けをしておく | |
if len(Xintlist) == 1: | |
if Xintlist[0] <= M: | |
print(1) | |
else: | |
print(0) | |
else: | |
# 位取り記数法の底が増えていくと、その位取り記数法におけるXの値も増えていく(狭義単調増加) | |
# よって、二分探索を用いる | |
# 二分探索の初期値を与える | |
# lowはd | |
low = d | |
# highはM+1 | |
high = M + 1 | |
# 二分探索を実施 | |
# lowとhighの差が1になるまで続ける | |
while low + 1 < high: | |
# lowとhighの平均をとる(小数点以下切り捨て) | |
mid = (low + high) // 2 | |
# mid進法におけるXintlistの値を取得 | |
value = Nshinhou(Xintlist, mid) | |
# 条件を満たしていれば、lowはmid以上の値であることが分かる | |
if value <= M: | |
low = mid | |
# そうでなければ、highはmid以下の値であることが分かる | |
else: | |
high = mid | |
# 二分探索の結果得られたlowとhighが境界 | |
# 出力するべきはlow - d | |
print(low - d) |
E以降
E以降は私の能力不足故に省略いたします.
参考にしたサイト等
- 「解説 - AtCoder Beginner Contest 187」
Editorial - AtCoder Beginner Contest 192
AtCoder is a programming contest site for anyone from beginners to experts. We hold weekly programming contests online.
- TATSUO IKURA様による「文字列の中の文字が大文字か小文字かを判定する(islower, isupper, istitle)」
>
文字列の中の文字が大文字か小文字かを判定する(islower, isupper, istitle)
文字列で用意されているメソッドの中で, 文字列の中に含まれる文字が大文字か小文字かを判定するのに使用できるメソッドの使い方について解説します.
- 渡部 拓也様による「アルゴリズムを勉強するなら二分探索から始めよう! 『なっとく!アルゴリズム』より」
アルゴリズムを勉強するなら二分探索から始めよう! 『なっとく!アルゴリズム』より
新しいサービスやプロダクトを開発するなら, アルゴリズムの理解はもはや欠かせなくなってきました. まだ理解が浅い, 勉強したいと思っている, そんな方には翔泳社が1月31日に刊行した『なっとく!アルゴリズム』をおすすめします. 今回は本書の読み方と, アルゴリズムの例として二分探索について紹介します.
0 件のコメント:
コメントを投稿 (Please feel free to ask me about your questions! You can use Japanese or English in the comments.)