成長観察日記

競プロとかPythonとかに関しての成長記録

ABC281振り返り

3完は、した。が、今まででいちばんメンタルやられた回だった…
B問題4ペナて、ひよこです。ピヨ
300の壁あついよお なんか300になってました!!!!超えた!!!!!!!!



A問題

atcoder.jp

問題概要

nから0まで改行カウントダウンしてくれよな

考察

  • forでiをプリント 以上

コード

#入力
n = int(input())

#逆からfor
for i in reversed(range(n+1)):
  print(i)

感想

Ryusukeさん(鬼)に教えていただいたreversed(range())かなり効き始めている。ありがたや
45秒でA問題解けたのは最速だったんだけれど…しかし……

ちなみに、開始前にターミナルにoj d 前コンテストのA問題idを変えただけのやつ を打っておけば開始と同時にDLできるの知った。
というか、問題文を見ずにサンプル見て判断したことと、もう一つ気になるのが
私のPC、問題文の表示までとダウンロードがなんか遅い。chrome拡張機能starshipが影響している気もする。要研究。



B問題

atcoder.jp

問題概要

文字列Sが以下の条件を満たしているか判定してね。

  • そのいち:頭1文字が英語の大文字
  • そのに:真ん中が100000〜999999までの整数
  • そのさん:おしり一文字が英語の大文字

考察

  • if文を書きまくるやつだ
  • そのいち、そのさん、はisupper()で英語の大文字なのかを判断しよう
  • 真ん中は切り出して .isdigit()で全部整数なのかを判断し、OKだったら範囲をint()変換して見よう

コード

#入力
s = input()

f = s[0] #1文字目
e = s[-1] #最後の文字
n = len(s) #sの長さ
m = s[1:-1] #2文字目〜最後から2文字目(整数であってほしい部分)


#整数であってほしい部分の判定 Falseならその後の整数判定でバグるためNoを吐き出しプログラム終了
if m.isdigit() is False:
  print('No')
  exit()

#残りの条件判定
if n == 8: #8文字?
  if f.isupper(): #最初の文字は英語大文字?
    if e.isupper(): #最後の文字は英語大文字?
     if 100000 <= int(m) <= 999999: #整数部分はご指定の範囲内?ご注文はうさぎ??
        print('Yes') #よくぞここまで辿り着いたYes
        exit()

#全部違ったらNo
print('No')

感想

まさか4ペナするとはおもわなんだ。
手元でいろんなパターン書きまくってエラー原因見つける回だった。プログラミングが下手…でも、学べるものめっちゃ多かった。

  • 条件が複数の判定問題については、無理にandで条件を繋げず、ひとつずつ入れ子する。今回は f.isupper() and e.isupper() と書いてて、右項を判断しない問題でやられた
  • ifに対してelse:print("no")を連発するのではなく、print("Yes")したらexit()で処理
  • 指定範囲に文字列が含まれていた場合、int変換の時にエラーが出るので、丁寧に場合分けしてあげる
  • ちゃんとサンプルケースでREする原因を特定してから提出する。もうまぐれでRE解決するほどのレベルではない。いい意味で!
  • そして、REが解決したからとてWAが取れるわけではないため、WA原因を特定し修正してから提出するようにする(本当にこれ)

なんか書き出したら怒り(?)落ち着いた。自分に対して怒ってた…散歩しよう。良い散歩を。



C問題

atcoder.jp

問題概要

n曲のプレイリストがある。各曲の長さはaの数列で与える。では再生!無限ループをするぞ!!さて、t分経った時、何曲目の何秒を聞いてるでしょう。

考察

  • 好きなものが題材の問題、とてもほっとする。
  • 止まった時間(t)を合計で余剰計算すれば、何ループ目かは関係なく現時点にいるところは確定できる。
  • 確定できたら、頭から時間を引き算していこう。

コード

#入力
n,t = map(int,input().split())
a = list(map(int,input().split()))

s = sum(a) #合計秒数
now = t%s #止まった時間、合計秒数中のどこにいるか
track = 0 #何曲目かを足してく変数

#止まった時間(nowいま)がiよりでかかったらnowからiを引く。トラックナンバーを加算
for i in a:
  if now >= i:
    now -= i
    track += 1
  else:
    track += 1
    break

print(track,now)

感想

落ち着いて解けたからよかった。
悔しいけど、やっぱり音楽に救われてしまう…てへ


D問題

atcoder.jp

問題概要

nこの数字からmこを選び足した結果をxとす。dの倍数になる最大のxを探してね。

考察

  • ソートして上から順に貪欲しようとする。
  • しかしこれは組み合わせの数的に無理だ、あ、まさか、これは噂の…DP…か…

感想

DPのDだよね。それだけはわかったよ。漸化式?数Bだね。おいしそうだね。全菓子機
アルゴ式をがんばります!!!

来週のburiodenは

実はちょっとでかい仕事があるけれど、寝なければ終わるのでがんばります。
土日はなんもないぜ!!いえええええええい精進いええええええええええええええええい
DPとBFSに命を捧げようとおもいます!!!

って、テンションで乗り切ろうとしないようにね。丁寧に場合分け…(トラウマ)

VScodeでnumpyが使えない!を解決した

波線が出てnumpyが使えない!を半年以上続けたやつ! やっと解決したよ!!



環境



結論

インタープリターの選択を正しくしたらいけた!!

  • Command + Shift + P

  • 普段使ってるやつを選択

  • \やったー/



やったこと

そもそもインストールされてるか確認

VScodeのターミナルで以下を叩く

$ pip list

出るやつ

Package                 Version
----------------------- -----------
.
.

jsonschema              4.16.0
lxml                    4.9.1
numpy                   1.23.5  #いる!!!
online-judge-api-client 10.10.1
online-judge-tools      11.5.1
.
.
.

いた。 いなかったら

$pip install numpy

こちらをターミナルで叩いてインストールしましょう



numpyの場所を確認する

叩くコマンド

$pip show numpy

出るやつ
「Location」を見ましょう

Name: numpy
Version: 1.23.5
Summary: NumPy is the fundamental package for array computing with Python.
Home-page: https://www.numpy.org
Author: Travis E. Oliphant et al.
Author-email: 
License: BSD
Location: /Users/XXX/.pyenv/versions/pypy3.8-7.3.7/lib/pypy3.8/site-packages    #ここ!!
Requires: 
Required-by: 



パス通ってるか見る

pythonファイルに以下を書き込み実行

import sys
import pprint

pprint.pprint(sys.path)

出るやつ の中に
pip show numpy で出てきた Locationの項目があるか確認

['/Users/XXX/Documents/今いる場所',
 '/Users/XXX/.pyenv/versions/pypy3.8-7.3.7/lib/pypy3.8',
 '/Users/XXX/.pyenv/versions/pypy3.8-7.3.7/lib/pypy3.8/plat-mac',
 '/Users/XXX/.pyenv/versions/pypy3.8-7.3.7/lib/pypy3.8/plat-mac/lib-scriptpackages',
 '/Users/XXX/.pyenv/versions/pypy3.8-7.3.7/lib/pypy3.8/site-packages']  #いる!!!

ここにいなければ、足してあげてください。 やり方はこちらを参考にするとよいです。

note.nkmk.me



そしてインタープリター選択

をしたら、無事にnumpyが使えました!やったね!!

使えるんだけどめっちゃ足りないやつがあるらしく、実行すると

/Users/XXX/.pyenv/versions/pypy3.8-7.3.7/lib/pypy3.8/site-packages/numpy/core/_add_newdocs.py:2922: UserWarning: add_newdoc was used on a pure-python object <bound method __class_getitem__ of <class 'numpy.ndarray'>>. Prefer to attach it directly to the source.
  add_newdoc('numpy.core.multiarray', 'ndarray', ('__class_getitem__',
/Users/XXX/.pyenv/versions/pypy3.8-7.3.7/lib/pypy3.8/site-packages/numpy/core/_add_newdocs.py:6243: UserWarning: add_newdoc was used on a pure-python object <bound method __class_getitem__ of <class 'numpy.dtype'>>. Prefer to attach it directly to the source.
  add_newdoc('numpy.core.multiarray', 'dtype', ('__class_getitem__',
/Users/XXX/.pyenv/versions/pypy3.8-7.3.7/lib/pypy3.8/site-packages/numpy/core/_add_newdocs.py:6755: UserWarning: add_newdoc was used on a pure-python object <bound method __class_getitem__ of <class 'numpy.number'>>. Prefer to attach it directly to the source.
  add_newdoc('numpy.core.numerictypes', 'number', ('__class_getitem__',

って出てきた後に結果が吐かれる

くう…でも使えるからとりあえずいいや

ABC280振り返り

長野県のめっちゃ暗いビジホで挑んだ!さむかった笑

また90分椅子をあたためつづける回!くやしー300越えたかったな
3度目の3完で、安定して茶パフォ出せるようになってきた!



A問題

atcoder.jp

問題概要

#と.がいくつか与えられる。#は何個あるか

考察

  • 配列の中の#の数はcount()で数えられる
  • ということはforで二次配列の中の # をcount("#")で数えて、足していこう

コード

#入力
h,w = map(int,input().split())
a = [input() for _ in range(h)]

#配列内の#の数を数えるためのans
ans = 0
#それぞれの配列の#の数をansに足していく
for i in a:
  ans += i.count("#")
 
print(ans)

感想

直前にこれを解いており、既視感で解けた。
こういう謎の運を発揮して試験に合格してきたなー



B問題

atcoder.jp

問題概要

ここに累積和(※)の数列がある。さていくつずつ足されたでしょうか?
※足し算の途中計算結果だと思うとわかりやすい。例えば[1,2,3]の累積和は[1,3,6]であり、1,1+2=3,1+2+3=6である。

考察

  • 累積和の逆をやればよいのか、なんか度数分布を埋めるやつでやったな…
  • 引き算していこう

コード

#入力
n = int(input())
s = list(map(int,input().split()))
 
#初期値セット
a = [s[0]]
 
#引いた数を格納していく
for i in range(1,n):
  a.append(s[i]-s[i-1])
 
#あんパック出力
print(*a)

感想

「やった」という感覚だった。
数学力つよめておくの本当に大事ね。



C問題

atcoder.jp

問題概要

文字列SとTがある。TはSの「どこか」に1文字が足されたものである。日本語の例だと
S「なまけもの」
T「なまけもの」
文字が足されてるのは何番目?

考察

  • SとTを一文字ずつ比較しよう
  • 追加されたのが最後だったパターンや、元々が2文字だったパターンに気をつけよう
  • そのために、絶対入力されない文字を足して、SとTの文字数を揃えておこう

コード

#入力 文字数足して数を揃えておく
s = input()+"Z"
t = input()

# いちおう長い方の長さに合わせてループ
for i in range(len(t)):
  if s[i] != t[i]: #違う文字があったら
    print(i+1) #iに+1して出力(インデックスは-1されてるので)
    exit() #出力したら強制終了

感想

はじめてコンテスト中にREしてふええってなった…でもわりとすぐに「n=2のパターンだ」と気付けて手元で実験、4分後無事にAC


D問題

atcoder.jp

問題概要

kの倍数になるn!は何?nを教えてくれ。

考察

  • そもそも階乗ってなんだっけ…
  • n = 4だったら 4 * 3 * 2 * 1 の計算結果だ
  • ということは、kの約数の中にnがいそう。だってその数を掛けないとkの倍数にならないし。
  • あとn!は必ずk以上になるな。そりゃそうだ倍数だし。
  • 素数は必ずk=nになりそう、約数がそれしかないし。
  • シミュレーションしか思いつかぬ…(爆死タイムアップ)

コンテスト後「つまりは探しにゆこう…僕らの…"最大公約数"を…

youtu.be

まず、素因数分解を考える

k = 30の場合

  • 30の因数は 30 / 2 / 3 / 5 = 1 >> [2,3,5]
  • つまり 2 * 3 * 5 = 30 = 5 * 3 * 2 * 1
  • 階乗にするには4が足りないぞ!4入れたら1 * 2 * 3 * 4 * 5で階乗になるのでnは5ですね!(あっ)

1 * 2 * 3 * 4 * 5 = 30 * 4

  • 掛け算の逆は割り算であることを利用 ていうか因数分解するから割り算する
    例えば 1 * 2 * 3 * 5 = 3030 / 2 / 3 / 5 = 1 は逆の関係
  • 1,2,3...のうち、k=30の因数にないものを飛ばしたい
    足りなかったから30に掛けた4の部分のこと
  • n/n = 1 の部分を見つけに行きたい

上記のご要望を叶える
301,2,3...それぞれの共通成分」つまり「GCD(最大公約数)」で割り続けると、n/n = 1 が出てきてくれる

計算してみると

  • 30と1のGCD は 1 >> 30/1 = 30
  • 30と2のGCD は 2 >> 30/2 = 15
  • 15と3のGCD は 3 >> 15/3 = 5
  • 5と4のGCD は 1 >> 5/1 = 5
  • 5と5のGCD は 5 >> 5/5 = 1

今こうやって見ると、最大公約数が1になった部分は因数ではないため 30 * 4 = 1 * 2 * 3 * 4 * 5となるからこの方法使ってるのかな。
まだよくわからない領域だ。なんて検索すれば出てくるのかもわからない。
緑diff、自力ACできるのは何ヶ月後なのだろうか…

コード

#gcd使うためにmathライブラリインポート
import math

#入力
k = int(input())
i = 0

#入力値の2*10**6までループ
while i < 2e6:
  i += 1
  k //= math.gcd(k,i)
  if k < 2:
    print(i)
    exit()
 
print(k)

感想

整数問題は奥が深くてすてきだ

来週(今週)のburiodenは

平日は意味がわからないくらい仕事が爆破しているけれど、土日は精進に集中できる!やったー!!
がんばるー!!!

バチャ精進、気が引き締まって良いです。たのしいよ。

ABC279振り返り

ライブ2本参戦号泣レンジャー後のABC、3度目の3完でした!
ご覧くださいこの提出時間!Dはいすをあっためたぜ!

1つの目標地点であった250を超え
Cまでがめっちゃ簡単に感じ
順位、パフォ、レート、級、全てが過去最高になった!
でも、なんか不完全燃焼でくやしい。なんでだろ



A問題

atcoder.jp

問題概要

vとwでできた文字列があるよ。下の部分…そう、尖ってる部分…の個数を教えてね。

考察

  • vはとんがり1
  • wはとんがり2
  • vとwの個数調べて、wはかける2して足すか

コード

#入力
s = input()

# vとwの数を数える
x = s.count("v")
y = s.count("w")

# wの数は*2して出力
print(x+(y*2))

感想

ひさぶりにA問題1分で解けてうれしみがふかい



B問題

atcoder.jp

問題概要

2つの文字列(文字列①、文字列②)がある。文字列①の中に、文字列②はありまっか?

考察

あるかないかを答えるだけじゃ

コード

# 入力
s = input()
t = input()


#tがsの中にあったらYes、なければNo
if t in s:
  print('Yes')
else:
  print('No')

感想

めっちゃどじってsとtを逆に書いてて1WAした…
sample case1つWAしてたのに何故かそのまま提出した
目が悪くなりすぎてきた よくない!自然にかえろう!!



C問題

atcoder.jp

問題概要

.と#でできた2つの表、それぞれ列を入れ替え完全一致となるか?

考察

  • 並び替えてもいいってことは、ソートすればいっか
  • 受け取りの時に列と行を入れ替えておこうzipだあ〜

コード

# 入力 2つの表はzipにて列と行を入れ替えてる
h,w = map(int,input().split())
a = zip(*[input() for _ in range(h)])
b = zip(*[input() for _ in range(h)])


# ソートして一致したらよき
if sorted(a) == sorted(b):
  print('Yes')
else:
  print('No')

感想

何度も制約を見た(ソートしてTLEするのではないかと)
歴代のCの中でいちばんかんたんに感じて、本当にこれ今ちゃんとコンテストの問題解いてる??って二度見した
Yes or Noと、クエリ処理の問題得意なのかもしれない


D問題

atcoder.jp

問題概要

数式が打てないので詳しくは問題を見てください
Bx + A//(x+1)**0.5 = 0のxを求め代入し出せばよろしいやつです

考察

  • A<B + (A/2**0.5)の場合は確実にそのままAを出力だなあ
  • 入力例と、分母が整数になるからって理由で、bの次の平方数を探してみる
  • 入力例1はACできたけれど、うーん、違う気がする
  • あ、方程式だ〜!Bx + A//(x+1)**0.5 = 0 解けない…AC何個つくかだけ見るために提出しよっと(撃沈)

コンテスト後 - 方程式を入れると解いてくれるAIがある…だと…??そういえばあったな…

https://ja.wolframalpha.com/input?key=&i=d%2Fdx+%28Bx%2BA%2F%28sqrt%281+%2B+x%29%29%29+%3D%3D+0

うわああ!!!!

  • しかし1行で書こうとすると計算が違ってしまうため、必殺!分子と分母をそれぞれ変数に入れてみた
  • 近似値も調べた方がよさそうだったので、2つ作ってminを出そう
import math

a,b = map(int,input().split())


c = pow(a,(2/3)) # 分子
m = pow(2,(2/3)) * pow(b,(2/3)) # 分母
x = math.floor(c / m)-1 # 求めたいx

# 操作行わなくていいパターン
if a < b + (a/2**0.5):
  print(a)
# 操作行うパターン
else:
  x1 = (b*(x)) + (a/((x+1)**0.5))
  x2 = (b*(x+1)) + (a/((x+2)**0.5))
  print(min(x1,x2))

感想

むずい………数学、すごく、すごくて、すごいなあ
中学数学やったおかげで方程式が立てられるようになったから、次からはWolframさんに頼って解を見つけられそう。がんばる!

来週のburiodenは

友達と富山で共喰い(ぶりを食べる)をした後、長野に移動し、また別の友達と蕎麦を食べ、ABCで一回抜けて、終了後は星を見ながらココアを飲みます!!!

んーどうして!!?!?!?

atcoder cli忘備録

結論から言うと常時使用は諦めた(えー!!!)



環境



経緯

qiita.com

  • 上記を参考に、online-judge-toolsとatcoder cliを入れてある
  • accについては、入れてはあるがうまく扱えず、ojtだけでDL→提出してる
  • コンテスト出る時もいちいちtestディレクトリ消してurlコピペしてターミナルに貼ってる
  • Githubに提出コード置いてるのかっこいい!そして便利そう!!
  • あ、そうか、atcoder cli使えばコンテストごとにディレクトリ作ってくれるから、ローカルに…提出を…溜めておける……(収集癖スイッチオン)
  • とはいえ精進の横道に逸れるから、ほどほどに研究してみよう



思い立ってからの流れ

ターミナルから、VScodeでファイル開けるようにする

なんでこれやってなかったんだろう…人生捗るよ……!

  • VScodeでCommand + Shift + P(コマンドパレット開く)
  • 「Shell Command: Install 'code' command in PATH」を叩く
$open ファイル名

の代わりに

$code ファイル名

と叩くと、VScodeで開かれてよきよきのよき!!

ついでに

$code .

で、今いるディレクトリをエクスプローラーとし開くことができてよき

挙動は「フォルダを開く」と同じ



acc new コンテストid を実行しても問題が選べない問題を解決っ

$ acc config

oj-path: /usr/local/bin/oj
default-contest-dirname-format: {ContestID}
default-task-dirname-format: {tasklabel}
default-test-dirname-format: tests
default-task-choice: all
default-template: cpp

本当に何もやっていなかった。C++時代の遺産じゃん

default-task-choice: allinquire

に変更すると、選択式にできた

$ acc config default-task-choice inquire

$ acc config

oj-path: /usr/local/bin/oj
default-contest-dirname-format: {ContestID}
default-task-dirname-format: {tasklabel}
default-test-dirname-format: tests
default-task-choice: inquire
default-template: cpp



acc sで提出できない問題を解決っ

ojtで提出用に設定されているディレクトリ名がtestなので、合わせてあげる

default-test-dirname-format: teststest

$ acc config default-test-dirname-format test

$ acc config

oj-path: /usr/local/bin/oj
default-contest-dirname-format: {ContestID}
default-task-dirname-format: {tasklabel}
default-test-dirname-format: test
default-task-choice: inquire
default-template: cpp



デフォルトテンプレートをpython

$ acc config default-template python

$ acc config

oj-path: /usr/local/bin/oj
default-contest-dirname-format: {ContestID}
default-task-dirname-format: {tasklabel}
default-test-dirname-format: test
default-task-choice: inquire
default-template: python



テンプレート設定

1.accの設定ディレクトリへ移動

$ cd `acc config-dir`

2.テンプレートディレクトリ作る(default-template:に設定した名前で)

$ mkdir python

3.移動する

$ cd python

4.テンプレートファイルと、設定用ファイル作る

$ touch test.py template.json

5.template.jsonに以下を追加

{
  "task":{
    "program": ["test.py"],
    "submit": "test.py"
  }
}

これでテストケースDL時にtest.pyも自動で作られ、提出もtest.pyのものが飛ぶ

6.横着なのでtest.pyによくある入力ケース入れておく

n = int(input())
n,m = map(int,input().split())

a = list(map(int,input().split()))
li = [list(map(int, input().split())) for _ in range(n)]



エイリアス登録

ターミナルで楽したい

ちなみにojt用には以下エイリアス登録している

alias tt='oj t -c "python3 test.py"'
alias gg='oj s test.py'
alias ggg='oj s --guess-python-interpreter pypy test.py'
alias rr='rm -r test'

いつものojdでの流れは

  • oj dの手打ち後、問題URL貼り付けてテストケースDL
  • コード書く
  • ttでテスト
  • ggでpython3提出
  • ※ライブラリ使ってなくてTLEこわい時はgggでpypy3提出
  • rrでテストケースフォルダ滅す

のループである



zshrc開く

$code ~/.zshrc

以下を追加

alias ag='acc s'
alias agg='acc s test.py -- --guess-python-interpreter pypy'
alias ad='acc add'

登録しておくと

  • acc new コンテストIDを手打ち
  • cd コンテストID/aで移動
  • test.py開き、コード書く
  • ttでテスト
  • agでpython3提出
  • ※ライブラリ使ってなくてTLEこわい時はaggでpypy3提出
  • adで次の問題へ



ちなみにVScodeショートカットにて

  • 「control(^) + T」ターミナルへ移動
  • 「control(^) + E」エディタへ移動

にしてあり、これもとても楽

エイリアス登録した後はコンソールをリフレッシュ(一度閉じて再度開く)しないと、せっかく作ったエイリアスが効かないから注意だ! ※まさかのハマった



使ってみて思ったこと

ディレクトリ移動がちょいめんどい

これはaccが悪いのではなく、私がojtオンリーに慣れすぎてしまったため…
cd〜を忘れてttを叩き謎の現象が起こりがち
解決策も教えてもらったけれど、知識足りてないからもう少し先かな…!

github.com

「acord」と「aprob」を参照するとよいそうです
シェル変数については

qiita.com

neko-mac.blogspot.com

圧倒的感謝…!!



ついついtest.pyの中身を消して新しいコード書いてしまう

これはaccが悪いのではなく、私がojtオンリーに略
テスト時に気付いて「あっ」てなる
提出をローカルに溜める目的も投げ出してしまう、手癖ってこわい…



提出時確認に叩く文字4つを打ち間違える

これはaccが悪いのではなく略
なかなかブラウザ開かないな〜って思ってたらターミナルが笑顔で入力待機している
ojtだとyだけで飛ぶのがいけない(そんなところが大好き)



これからどうするか

  • 普段の精進はojtのまま
  • コンテストはacc利用

かな、と思っている

理由としては

  • 最初やりたかったACコードをローカルストックしておく(いずれGithubに上げる)は、atcoder plobremsのAPIで定期的にやればよさそう(いつも教えていただき本当に感謝です…!)

zenn.dev

  • 600問で積み重ねてきた手癖を修正する元気がない(!!)

  • とはいえコンテスト時は、問題URLをコピペるよりも以下手順の方が速そう

    • acc new abc279などの状態で待機。21:00に実行
    • ダウンロードしてる間に問題ページへ移動
    • その時くらいはcd abc279/aしてあげるわよ
    • よくある入力入ったテンプレ開かれるのは魅力的だわよ
    • たぶん提出の4文字もそこまで気にならないわよ

という、ひよこの予想

もし

「こうすると楽だよ!」

「ここ間違ってるよ!」

「こうもできるよ!」

などなどあったら、ビシバシ教えていただけると、とってもとってもうれしです…!

ABC278振り返り

2度目の3完!
Dも時間内にTLEでは通せたし、ほんの3行の違いだった
過去最高につよかった!!



A問題

atcoder.jp

問題概要

n個の数字に対して「最初のやつ消して、最後に0を追加する」をk回やってほしい

考察

  • 頭に0を追加してn個にしたものを反転しようとして「あ、違う」と気付いた。
  • まず、n(数字の数)よりk(操作の回数)が大きい場合は全部0になる。
  • そうでなくとも、最初のものは必ずk個消される、つまりk番目以降は必ずある。
  • そして、nまでの足りない分は0を追加すればよし。

コード

# 受け取り
n,k = map(int,input().split())
a = list(map(int,input().split()))

# nよりkがでかかった時
if n <= k:
  # 0をn個、半角スペース空けて出力したい
  # そうだ配列をアンパックして出力しよう!
  print(*[0]*n)
# nよりkがちっちゃかった時
else:
  # 「数列aのa[k]から先のものと、0をk個」を合体して出力
  print(*a[k:]+[0]*k)

感想

問題文が読めなかった(?!)久しぶりにAに5分以上かかり無念だ!!



B問題

atcoder.jp

問題概要

デジタル時計の「20:23」って表示、もし時と分の表示がタテに並んでたら「22:03」って見間違えちゃうよね。その時刻がありえないやつ…例えば「19:11」を見間違えて「11:91」だったら、びっくりしちゃうよね!もしそうだったら、次に迎える、見間違えてもびっくりしない時刻(20:00と20:00)を教えてー!

考察

  • まず、見間違えてもびっくりしない時刻の域を考える

    • 時間の2桁目 : 0〜2

    • 時間の1桁目 : 0〜5

    • 分の2桁目 : 0〜5

    • 分の1桁目 : なんでもおk(0〜9)

  • つまり、見間違えてびっくりするやつ

    • 6時〜9時、16時〜19時

    • 20時〜23時のそれぞれ40分以降

は、次の大丈夫な時刻を表示してあげればヨシ
見間違えてもびっくりしない時刻なら、そのまま出力してあげる

コード

# 受け取り
h,m = map(int,input().split())

# 6時〜9時
if 6 <= h <= 9:
  # 次のびっくりしない時間は10時00分
  print("10 0")
# 16時〜19時
elif 16 <= h <= 19:
  # 次のびっくりしない時間は20時00分
  print("20 0")
# 23時
elif 23 == h:
  # 40分以降は
  if 40 <= m:
    # 0時0分
    print("0 0")
  # 39分までは
  else:
    # そのままでもびっくりしない
    print(h,m)
# 20時〜22時の
elif 20 <= h:
  # 40分以降は
  if 40 <= m:
    # 時に+1の0分
    print(h+1,0)
  # 39分までは
  else:
    # びっくりしない
    print(h,m)
# 他は全部びっくりしない
else:
  print(h,m)

感想

むずくね???シミュレーションの方法が思いつかなかったから、丁寧に場合分けした。
そもそも問題を理解するまでに30分かかった!めっちゃお絵描きした!
Bに40分かかるなんてまだまだひよこだな(にわとり目線)
直前else忘れに気付けて本当によかった…!!



C問題

atcoder.jp

問題概要

SNSの闇データ…n人の人間たちのフォローとリムの記録をあげるよ。記録の最中、たまに「こいつら今、相互フォローしてる?」って聞くから、YesかNoかで答えてね。

考察

そうだフラグ管理をしよう!

例えば3人の記録

[

[0,0,0], // 1人目

[0,0,0], // 2人目

[0,0,0] // 3人目

]

1人目が2人目をフォローしたら

[

[0,1,0], // 1人目 が 2人目(2番目)をフォローした!

[0,0,0], // 2人目

[0,0,0] // 3人目

]

って感じにして、リムったら1を0にしよう

コード

# 都合のよく高速な(?!)辞書を使えるようにするライブラリを読み込む
from collections import defaultdict

# 受け取り
n,q = map(int,input().split())
# フォロー記録リストの二次元辞書をつくる
# n = 3なら [0,0,0],[0,0,0],[0,0,0]ってリストが作られるイメージ
# 辞書なので、重複処理は排除される
w = defaultdict(lambda :defaultdict(list))

# クエリ処理
for i in range(q):
  t,a,b = map(int,input().split())
  # インデックス管理楽にするために-1
  a -= 1
  b -= 1
  # クエリその1 aがbをフォローする
  if t == 1:
    w[a][b] = 1 # a人目のデータの中、b人目のフォロー状況チェックを1に
  # クエリその2 aがbをリムる
  elif t == 2:
    w[a][b] = 0 # a人目のデータの中、b人目のフォロー状況チェックを0に
  # クエリその3 相互フォローチェック
  elif t == 3:
    # a人目データの中 b人目のフォロー状況と、b人目データの中 a人目のフォロー状況が共に「1」だったら
    # (データを覗いた時「1」ならTrueだから、True and Trueで全体Trueになる)
    if w[a][b] and w[b][a]:
      print('Yes')  # ハッピーだね!Yes!
    else:
      print('No') # 片思い、または両方思ってないなら悲しいね、No

感想

やっぱりまだ計算量の計算が苦手で、n個の二次配列の中でn個の0をループして作って爆死。
TLE原因がわからないまま、連結リストチックなことappendでやって爆死
「そういえばなんかいい感じの辞書あった気がする…」と思い出し、自分のコードを引っ張り上げてAC!
でも実際まだdefaultdictのことよくわかってない。
TLEを阻止する要感まんまんだから、たまにはちゃんとpythonのお勉強をするーー!!
あと計算量も…アルゴ式…!!(依存)



D問題

atcoder.jp

問題概要

値がn個の数列に対して、以下処理を行なってくれよな

  • 処理1:全部yにする
  • 処理2:i番目にyを足す
  • 処理3:i番目を出力する

考察

言われたままやるしかねえっっ

コード

# いつもありがとう辞書
from collections import defaultdict

# 受け取り
n = int(input())
a = list(map(int,input().split()))
q = int(input())

for i in range(q):
  # クエリ番号をxとして入力
  # 残りは、1桁の時y[0] 2桁ならy[0]とy[1]として処理するためあんパック入力
  x,*y = map(int,input().split())
  # 処理その1
  if x == 1:
    ad = y[0] #置き換える数字を指定
    a = defaultdict(lambda:ad) #指定した数字をキーにして、数列を作り替える
  # 処理その2 指定されたindexに加算
  elif x == 2:
    a[y[0]-1] += y[1]
  # 処理その3 指定されたindexを出力
  elif x == 3:
    print(a[y[0]-1])

感想

まさかD問題があと一歩で解けるところまで来るとは…
コンテスト中のTLEコードとコンテスト後に他の人の提出見てACしたコードの比較、見てほしい

from collections import defaultdict #これを追加

n = int(input())
a = list(map(int,input().split()))
q = int(input())

for i in range(q):
  x,*y = map(int,input().split())
  if x == 1:
    # a = [y[0]]*n コンテスト中の敗因を
    ad = y[0] #これに書き換え
    a = defaultdict(lambda:ad) #これに書き換え
  elif x == 2:
    a[y[0]-1] += y[1]
  elif x == 3:
    print(a[y[0]-1])


計算量ダメだろうな〜ってわかってるのにダメ元で出してしまう、ってのが次に越えるべく壁だなあ
茶diffが解けるようになったの本当に嬉しい!成果〜〜!!

来週のburiodenは

これの昼公演行ったあと

stars-dreamlive.com

このライブに行き

はい、その後に
前回神の家で参加するも0完をした、因縁のトヨタコンに…出ます……(白目)