Python3で解く AtCoder Beginner Contest 185 D - Stamp
結構単純な、数え上げするだけ。 問題を把握するのに、少しだけ苦戦したがよく読んだらDにしては結構単純だった。
目次
概要
問題概要は省略。
解くときに考えた内容
- 最初と最後を同等に考えられる様にとをリストに加える。
(元のリストのうち、最初と最後の値を同等に扱える必要にするため結構キモ) - 更にソートする。
- 具体的に言うと入力例1だと →
- 0以上の差分のリストを作成する(間にいくつ数値があるかという意味で)
- →
- この時点で、0以上の差分のリストに値がなければ、白がないということ。
- は0以上の差分のリストの最小値になる。
- そうでないと、どう取ってもかならず白を含んでしまうため
- 差分のリストに含まれる値をで割って、切り上げた値を足し上げていく。
- 切り上げのイメージはX:白、O:青、△:赤として、XOOOOOXを例えばでで△で埋めていくことを考えると割り切れる範囲はX△△△△OXのようなイメージで割り切れない部分は1度重なるようにしてX△△△△△Xとする必要があるから、切り上げするイメージ。
コード
n, m = map(int, input().split()) a = [int(x) for x in input().split()] # 最初と最後を同等に考えられる様に # 0とn+1をリストに加える a.append(0) a.append(n+1) # print(a) num = len(a) a_s = sorted(a) l = list() for i in range(num-1): c = (a_s[i+1] - a_s[i] - 1) # print(c) if c > 0: l.append(c) # print(l) if len(l) == 0: print(0) else: k = min(l) cnt = 0 for i in l: # 切り上げ if i % k == 0: cnt += i // k else: cnt += i // k + 1 print(cnt)
参考になる書籍
- 問題解決力を鍛える!アルゴリズムとデータ構造
けんちょんさんこと、大槻さんの書籍である、「問題解決力を鍛える!アルゴリズムとデータ構造」 ご本人の記事の中で難易度は、螺旋本ということで初学者でも非常に結構読みやすい!!!(実際に、けんちょんさんの記事はC++に疎い自分でも、その思考プロセスを学べるくらい丁寧に書かれているし、この書籍も非常に読みやすい)どのようなステータスの人にもおすすめの一冊になっている。
とうとう発売され自分の手元にも来た(2020-10-03)。現在読み中なのである程度読み込んだら感想を書く予定。めっちゃ図が多いし、章末問題もあるしかなりイケてる。答えはC++で書かれているがそのうちPythonでも書かれるとのことなので、自分で前もってやってしまおうと思う(答え合わせできるのはありがたい)。
問題解決力を鍛える!アルゴリズムとデータ構造 (KS情報科学専門書)
- 作者:大槻 兼資
- 発売日: 2020/10/02
- メディア: 単行本
7章までは別記事に残してある。 blacktanktop.hatenablog.com
AtCoder Beginner Contest 185 参加ログ・感想
意味不明なやり方して頭大混乱で、絶対に落としちゃいけないCを落としてしまった・・・
内容
- Python3でやっている。
- 参加ログ。
- 所感。
- コンテスト中に何を考えたか。
- コンテスト後に解説をみたり、少し整理したりしたくらいの内容。
- 問題の詳細で細かく書こうと思うものは別記事とする。
結果
AB完。Cはただのコンビネーションでとにかく11箇所を選ぶだけの計算だったのにわけわからんこと考えて終了なぜパニクるのかもよくわからんし、さらにPythonならオーバーフロー気にせずできる。Dは、マスのリストをソートして、差分を取って、一番小さい値で差分を割って切り上げを足すだけ。あとから考えると結構ラッキー回だったのにできなかったのは実力不足Orz
どう考えたか + α
A - ABC Preparation
問題タイプ:最小値
文意から問題数が最も小さい値が答え。
a = [int(x) for x in input().split()] ans = min(a) print(ans)
B - Smartphone Addiction
問題タイプ:クエリ処理・条件分岐 初期に持っているバッテリー値に対して、
- 以降の変化するバッテリー値 とする。
- - 前回のの値()を引く。(状況:歩いている時間)
- 初回はを引く。
- この時に になったら'No'
- を足す。(状況:カフェで充電)
- この時に になったらとする。(状況:満充電)
- 次のクエリのと引き算するためにを保持しておく。(状況:カフェ出た時間の保持)
なんか、結構条件をきちんと書き上げるだけなんだけど、条件分岐も多くて結構ハマった。
n, m, t = map(int, input().split()) ab = [list(map(int, input().split())) for _ in range(m)] _b = 0 bat = n for a, b in ab: _a = a - _b _b = b - a bat -= _a if bat <= 0: print('No') exit() bat += _b if bat > n: bat = n _b = b if t - _b < bat: print('Yes') else: print('No')
C - Duodecim Ferra
問題タイプ:組み合わせの数え上げ
文意から、とにかく箇所切るところを選ぶ選び方。つまり Pythonの場合はオーバーフローは気にせず。分子と分母を別々に計算して割り算するだけ。
l = int(input()) # l-1から11を選ぶ選び方 a, b = 1, 1 for i in range(1, 12): # 分子 a *= l-i # 分母 b *= i print(a//b)
おわりに
今回は、絶対わからんっていう感じでもなかったのに、解ききれないといった感じ。またRatingは少し下がってしまった。沼はまだ深い・・・。
参考になる書籍
- 問題解決力を鍛える!アルゴリズムとデータ構造
けんちょんさんこと、大槻さんの書籍である、「問題解決力を鍛える!アルゴリズムとデータ構造」 ご本人の記事の中で難易度は、螺旋本ということで初学者でも非常に結構読みやすい!!!(実際に、けんちょんさんの記事はC++に疎い自分でも、その思考プロセスを学べるくらい丁寧に書かれているし、この書籍も非常に読みやすい)どのようなステータスの人にもおすすめの一冊になっている。
問題解決力を鍛える!アルゴリズムとデータ構造 (KS情報科学専門書)
- 作者:大槻 兼資
- 発売日: 2020/10/02
- メディア: 単行本
7章までPythonで章末問題をこなしていっている。
Python3で解く AtCoder Regular Contest 110 B - Many 110
きれいに条件分岐ができればいい。
最初'0'にアサインできたら、最後、左から数えて何番目の'0'にアサインできるかを考える問題
概要
- 文字列は'110'が個連結したものである。
- 文字の文字列が与えられる。
- にが連続する部分文字列としていくつ含まれる?
解くときに考えた内容
- の長さ別に考える。
- が1文字の場合
- = '1'の場合
- ('110'に2つ'1'があるから)
- = '0'の場合
- ('110'に1つ'1'があるから)
- = '1'の場合
- が2文字の場合
- = '11'と'10'の場合
- ('110'に1つ'11'または'11'があるから)
- = '01'の場合
- (最後の1つは取れないので-1)
- = '00'の場合
- (このパターンはないので)
- = '11'と'10'の場合
- が3文字以上の場合は0が があるので、の0のどこまでアサインできるかということになる。
- の長さを3で割って切り上げる。
- この値はに含まれる0の個数であり、cntとする。
- ここで、'110'をcnt分連結した文字列に含まれるかどうかで、カウント対象であるかと、その文字列が0で終わっているのか1で終わっているのかを同時に判定する(結構キモ)
- '110'をcnt分連結した文字列にtが含まれるなら、tが0終わりでsに存在ということ。
- 例えば、
- 0110とすると、cnt = 2であり、の0の最後……11'0110'、個目まで取れる。
- 0110110とすると、cnt = 3であり、の0の最後……11'0110110'、個目まで取れる。
- 一般に、となる。
- 例えば、
- '110'をcnt分連結した文字列にtが含まれず、'110'をcnt分+1連結した文字列にtが含まれるなら、tが1終わりでsに存在ということ。
- 例えば、
- 011とすると、cnt = 1であり、の0の最後……11'011'0、個目まで取れる。
- 011011とすると、cnt = 2であり、の0の最後……11'011011'0、個目まで取れる。
- 一般に、となる。
- これらに当てはまらないものは にが含まれないので
- 例えば、
上図のように、 が3文字以上でに含まれるその他のパターンも同じ様に書いてみると、最初'0'にアサインできたあと、最後の左から数えて何番目の'0'にアサインできるかを考える問題であると言うことがわかる。
コードは全場合分けベースで書いたものと、 が2文字のものも3文字のものと同様に考えて問題ないので、2種類にかき分けた。
コード
全部場合分け
n = int(input()) t = input() m = 10**10 # 切り上げ if len(t) % 3 == 0: cnt = len(t) // 3 else: cnt = len(t) // 3 + 1 # sにtが存在する出力パターン # tのサイズが1のとき if t == '1': print(2*m) elif t == '0': print(m) # tのサイズが2のとき elif t == '11' or t == '10': print(m) elif t == '01': print(m-1) elif t == '00': print(0) # tのサイズが3以上のとき elif len(t) >= 3: # この書き方ならt = 0, 11などもここに含めても可能 # 個数倍復元して含まれているなら、tが0終わりでsに存在 if t in '110' * cnt: print(m-cnt+1) exit() # 上記でなくて個数倍+1で復元して含まれているなら、tが1終わりでsに存在 elif t in '110' * (cnt+1): print(m-cnt) exit() # 上記以外はsにtが存在しない出力パターン else: print(0)
最低限
n = int(input()) t = input() m = 10**10 if len(t) % 3 == 0: cnt = len(t) // 3 else: cnt = len(t) // 3 + 1 # tが1のとき if t == '1': print(2*m) exit() # それ以外の時(tが0や、2文字以上のときはこの記述で集約できる) if t in '110' * cnt: print(m-cnt+1) # 上記でなくて個数倍+1で復元して含まれているなら、tが1終わりでsに存在 elif t in '110' * (cnt+1): print(m-cnt) # 上記以外はsにtが存在しない出力パターン else: print(0)
参考になる書籍
- 問題解決力を鍛える!アルゴリズムとデータ構造
けんちょんさんこと、大槻さんの書籍である、「問題解決力を鍛える!アルゴリズムとデータ構造」 ご本人の記事の中で難易度は、螺旋本ということで初学者でも非常に結構読みやすい!!!(実際に、けんちょんさんの記事はC++に疎い自分でも、その思考プロセスを学べるくらい丁寧に書かれているし、この書籍も非常に読みやすい)どのようなステータスの人にもおすすめの一冊になっている。
とうとう発売され自分の手元にも来た(2020-10-03)。現在読み中なのである程度読み込んだら感想を書く予定。めっちゃ図が多いし、章末問題もあるしかなりイケてる。答えはC++で書かれているがそのうちPythonでも書かれるとのことなので、自分で前もってやってしまおうと思う(答え合わせできるのはありがたい)。
問題解決力を鍛える!アルゴリズムとデータ構造 (KS情報科学専門書)
- 作者:大槻 兼資
- 発売日: 2020/10/02
- メディア: 単行本
7章までは別記事に残してある。 blacktanktop.hatenablog.com
Python3で解く AtCoder Regular Contest 110 A - Redundant Redundancy
問題の制約がゆるすぎて、のときの答えをprintするだけで終わる。
print(2329089562801)
なので、解説記事としては候補のうち最小という状態で考えるとした場合にする。
目次
概要
- 整数が与えられる。
- からまでのすべての整数で割って余りがになるような 以上 以下の値は?
この制約が甘いので、がどんな値でものときの答えを書けば良くなる。
解くときに考えた内容
上記のような事があるとしても、考え方としては、でも一緒。
文意から、 からまでのすべての整数で割り切れる数にを足せば、条件を満たす。
ちなみに記事冒頭の値は、30以内の素数を何回かかけた値のうち30以内のものをかけ合わせた値+1である
# 上記のコードでn=30としたときの値を入れてもACにはなる print(2329089562801) # ちなみにこれは、30以内の素数を何回かかけた値のうち30以内のものをかけ合わせた値+1である # 30以内の素数:2, 3, 5, 7, 11, 13, 17, 19, 23, 29 print(2**4 * 3**3 * 5**2 * 7 * 11 * 13 * 17 * 19 * 23 * 29 + 1) # 2329089562801
コード(候補のうち最小とするならば以下)
def gcd(a, b): if b == 0: return a else: return gcd(b, a%b) def lcd(a, b): return int(a / gcd(a, b)) * b def mod_lcd(n, mod): ans = 1 for i in range(2, n+1): ans = lcd(ans, i) return ans + mod n = int(input()) ans = mod_lcd(n, 1) print(ans)
参考になる書籍
- 問題解決力を鍛える!アルゴリズムとデータ構造
けんちょんさんこと、大槻さんの書籍である、「問題解決力を鍛える!アルゴリズムとデータ構造」 ご本人の記事の中で難易度は、螺旋本ということで初学者でも非常に結構読みやすい!!!(実際に、けんちょんさんの記事はC++に疎い自分でも、その思考プロセスを学べるくらい丁寧に書かれているし、この書籍も非常に読みやすい)どのようなステータスの人にもおすすめの一冊になっている。
とうとう発売され自分の手元にも来た(2020-10-03)。現在読み中なのである程度読み込んだら感想を書く予定。めっちゃ図が多いし、章末問題もあるしかなりイケてる。答えはC++で書かれているがそのうちPythonでも書かれるとのことなので、自分で前もってやってしまおうと思う(答え合わせできるのはありがたい)。
問題解決力を鍛える!アルゴリズムとデータ構造 (KS情報科学専門書)
- 作者:大槻 兼資
- 発売日: 2020/10/02
- メディア: 単行本
7章までは別記事に残してある。 blacktanktop.hatenablog.com
Python3で解く AtCoder Beginner Contest 153 D - Caracal vs Monster
愚直に、1~hまでどんな風になるかをリストで残そうとすると、TLEになる様な制約なので、いい感じのパターンを見つける必要がある。
どんな人数になるかがちょっとよくわからないので、とりあえず書き出す。そうするとパターンが見えてくる。
目次
概要
- モンスターが1体いて体力は。
- モンスターを攻撃する。
- その時にモンスターの体力が なら倒せる。
- その時にモンスターの体力が より大きい時は、体力が半分(切り下げ)になって、2体になる。
- 攻撃回数の最小となるような攻撃回数は?
解くときに考えた内容
- サンプルをみると、1, 3, 3, 7となっている。
- DPっぽくやるのかなとおもったけどモンスターの体力の制約が なので、無理そう。
- モンスターの体力が が1, 3, 7, 15の時は攻撃回数も1, 3, 7, 15。 モンスターの体力が が1, 2, 4, 8の時は攻撃回数も1, 3, 7, 15。 つまり、hがの範囲であれば、必要な攻撃回数はということになる。 (画像に番目って書いてあるけどhの値だったな。。。)
- なので、まで調べれば良いので
コード
h = int(input()) ans = 1 if h >= 1: i = 0 while 2**i <= h: ans = 2**(i+1) - 1 i += 1 print(ans)
参考になる書籍
- 問題解決力を鍛える!アルゴリズムとデータ構造
けんちょんさんこと、大槻さんの書籍である、「問題解決力を鍛える!アルゴリズムとデータ構造」 ご本人の記事の中で難易度は、螺旋本ということで初学者でも非常に結構読みやすい!!!(実際に、けんちょんさんの記事はC++に疎い自分でも、その思考プロセスを学べるくらい丁寧に書かれているし、この書籍も非常に読みやすい)どのようなステータスの人にもおすすめの一冊になっている。
とうとう発売され自分の手元にも来た(2020-10-03)。現在読み中なのである程度読み込んだら感想を書く予定。めっちゃ図が多いし、章末問題もあるしかなりイケてる。答えはC++で書かれているがそのうちPythonでも書かれるとのことなので、自分で前もってやってしまおうと思う(答え合わせできるのはありがたい)。
問題解決力を鍛える!アルゴリズムとデータ構造 (KS情報科学専門書)
- 作者:大槻 兼資
- 発売日: 2020/10/02
- メディア: 単行本
7章までは別記事に残してある。 blacktanktop.hatenablog.com
Python3で解く AtCoder Regular Contest 109 B - log
長さの丸太を買って、短い方から丸太を作れるだけ作って、残りは買う。 -(作れるだけ作った数)+ 1が答え。作れるだけ作った数をどうかんがえるかがポイント
目次
概要
- 長さからの種類の丸太がほしい。
- 長さからが各ずつ、各1円で売ってる。
- 自由に切ってよい。例えば長さの丸太を長さと長さとしていい。
- 余ったものは捨ててよい。
- このとき、が与えられたときに、長さからの種類の丸太を用意する最小の金額は?
解くときに考えた内容
長さの丸太を買って、短い方から丸太を作れるだけ作って、残りは買う方針でいく。これが最小なのは自明ではないが、証明はしない。
から作れるだけ作るときに長さのの最大値を求める必要がある。
のような数列とを比較して、最大のを求めたい。
等差数列の和の数列なので、のリストを制約分作ってもいいけど、作ると終わらない。
bisectはリストが無いとできないので、ここでは使えない。
ここでは、リストがない状態での二分探索を行う必要がある。(これまで、なぜわざわざこのような実装しているのかわからないときがあったが、このような状況のときに有効ということがわかった。)
普通の二分探索の実装で、とmidの値と比較するべきところをと等差数列の和としてを比較するようにして、探索していくようにする。
コード
def log_cut(n): l = 0 r = n while r - l > 1: mid = (l+r) // 2 # ここの比較がポイント # リストも与える二分探索だとlist[mid]とn+1を比較するが # 今回はリストではなく、mid自体の値を使って、等差数列の和と比較する。 if mid * (mid+1) // 2 <= (n+1): l = mid else: r = mid return l n = int(input()) # これが作れる分のkの最大値 max_log = log_cut(n) # n - max_log(買う分)+ (1, 2, ... , kは1本) ans = n - max_log + 1 print(ans)
参考になる書籍
- 問題解決力を鍛える!アルゴリズムとデータ構造
けんちょんさんこと、大槻さんの書籍である、「問題解決力を鍛える!アルゴリズムとデータ構造」 ご本人の記事の中で難易度は、螺旋本ということで初学者でも非常に結構読みやすい!!!(実際に、けんちょんさんの記事はC++に疎い自分でも、その思考プロセスを学べるくらい丁寧に書かれているし、この書籍も非常に読みやすい)どのようなステータスの人にもおすすめの一冊になっている。
とうとう発売され自分の手元にも来た(2020-10-03)。現在読み中なのである程度読み込んだら感想を書く予定。めっちゃ図が多いし、章末問題もあるしかなりイケてる。答えはC++で書かれているがそのうちPythonでも書かれるとのことなので、自分で前もってやってしまおうと思う(答え合わせできるのはありがたい)。
問題解決力を鍛える!アルゴリズムとデータ構造 (KS情報科学専門書)
- 作者:大槻 兼資
- 発売日: 2020/10/02
- メディア: 単行本
7章までは別記事に残してある。 blacktanktop.hatenablog.com
Python3で解く AtCoder Regular Contest 109 A - Hands
状態を把握するのに、ちょっと時間はかかったが、イメージはできた。しかし場合分けが多く、そこにハマったのでまとめる
目次
概要
- 100階建ての建物 がある。
- とは廊下でつながっていて、分かかる。
- とは廊下でつながっていて、分かかる。
- とおよびとは階段でつながっていて、分かかる。
- 与えられた、階から階へ最短時間で移動したときの時間は?
解くときに考えた内容
まずイメージ図
- 文意から、100階建ての建物 は上の一番左のようになっている。
- の大小で降りる手段として、廊下か階段かを選択すべきかがわかり、最後はへ移動するのにという構図。降りるときと登るときとでことなるのは降りるときしかへ移動できないので、そこで場合分けが必要。
- まずは、が同じフロアの場合、もしくはからが1階降りる場合。
- が最短。
(なぜなら、なので、は自明)
- が最短。
- 次に2階以上降りる場合。
- を とすると
- ということ。
- 1階おりるのにのとき、廊下を選んでで 階降りて、最後に で へ行く
- 1階おりるのにのとき、階段を選んでで 階降りて、最後に で へ行く
- 次に1階以上登る場合。
- これ上記のをと考えればいい。
コード
a, b, x, y = map(int, input().split()) step = b - a if step == 0 or step == -1: ans = x # 下に-1を含めても良い。結果xになるから elif step <= -2: if y >= 2 * x: ans = (abs(step)-1) * 2 * x + x else: ans = (abs(step)-1) * y + x elif step >= 1: if y >= 2 * x: ans = step * 2 * x + x else: ans = step * y + x print(ans)
終わりに
結構きれいに場合分けしないと、うまく行かない。絵に書けばだいたい分かるが、時間かかりすぎた。
参考になる書籍
- 問題解決力を鍛える!アルゴリズムとデータ構造
けんちょんさんこと、大槻さんの書籍である、「問題解決力を鍛える!アルゴリズムとデータ構造」 ご本人の記事の中で難易度は、螺旋本ということで初学者でも非常に結構読みやすい!!!(実際に、けんちょんさんの記事はC++に疎い自分でも、その思考プロセスを学べるくらい丁寧に書かれているし、この書籍も非常に読みやすい)どのようなステータスの人にもおすすめの一冊になっている。
とうとう発売され自分の手元にも来た(2020-10-03)。現在読み中なのである程度読み込んだら感想を書く予定。めっちゃ図が多いし、章末問題もあるしかなりイケてる。答えはC++で書かれているがそのうちPythonでも書かれるとのことなので、自分で前もってやってしまおうと思う(答え合わせできるのはありがたい)。
問題解決力を鍛える!アルゴリズムとデータ構造 (KS情報科学専門書)
- 作者:大槻 兼資
- 発売日: 2020/10/02
- メディア: 単行本
7章までは別記事に残してある。 blacktanktop.hatenablog.com