tooh’s diary

半角全角、常体敬体が入り乱れるカオス

2/14 AtCoder(大文字小文字、円と四角形の内包、joinを使ったリスト内要素の区切り方、リストのコピー)/ss

AtCoder
解くに至ったもの(14問)
ABC:018A/072D/094D
ARC:045A/046A/047A/049A/050A/051A/053A/054A/055A/056A/080D

 

ARC050A

文字を大文字、小文字にする

大文字は

(文字列).upper()

小文字は

(文字列).lower() とすればよい

 

他にも、文字列すべての大文字小文字を逆にするには

(文字列).swapcase()

先頭一字のみ大文字にするには、

(文字列).capitalize() が使える

 

ARC051A

普通に解法が思いつかなかった 大丈夫か

円が長方形に内包されている→中心からxy方向それぞれに半径だけ伸ばした部分が長方形の四つの辺の内側にあるかどうかを調べる

長方形が円に内包されている→四つの(四つ。二つだとダメ)頂点が円の内側にあるかどうかを調べる(中心との距離を使う)

 

ARC080D

これも解法が思いつかなかった 色を盤面に塗り付けていく問題

色でタイルを塗る枚数が指定されていて、それぞれの色がその中で一筆書きできるようにするにはどうしたらいいかというもの

結局左上から蛇行するように右、左、右、左と進んでいけばよい 進んで色を塗り付けていくコードを書くのは簡単

問題は出力で、例えば

M = [[1,2,2,3,3],[4,4,4,4,3],[5,5,5,5,5]]を

1 2 2 3 3 

4 4 4 4 3

5 5 5 5 5

と出力するにはどうしたらよいか

こういう時は、

for j in range(3):
  print(' '.join(map(str,M[j])))

とする

printの中にはjoinという関数がある。これは、'?'.join(リスト)とすることで 

リストの要素(文字に限る)を?で区切った形で出してくれるというもの

例えば、

L = [a,bc,d]というリストを

a_bc_d

と出力したい場合、

print('_'.join(L))

とすればよい

 

んで、今回の場合、空白区切りで数字を出力したいということになる。数字は残念ながら扱えないので、一度文字列に直してから動かすという手法をとる

 

M = [[1,2,2,3,3],[4,4,4,4,3],[5,5,5,5,5]]を
1 2 2 3 3
4 4 4 4 3
5 5 5 5 5

と出力するには、

for j in range(3):

  print(' '.join(map(str,M[j])))

とする 

これは

①3回にわたって(改行して)リストに入れ子になっているリストを出すという発想を念頭に置いておき、printの部分で、

②' '.join は空白で区切って要素を出す

③リストの所に入っている map(str,M[j]) は、M[j]の要素を文字列に変換する 

という操作を行っている

 

この問題では使わなかったけど、リストのコピーをするときは

(新しいリスト) = copy.deepcopy(コピー元のリスト)

とするとよい

copy.copy(コピー元のリスト)というやり方もあるにはあるけど、これは新しく作ったリストの方で操作をすると、コピー元のリストもその変更が適用されてしまうという点で使い勝手がわるい

 

 

解けなかったもの

全国統一なんちゃら:C

ARC:091D

 

全国統一プログラミング王決定戦予選C

普通にわからず リストを用意して番号を前から1,2,3......って振ってコピー→A,Bの大きい順でソート→食べていった端からリストの番号に対応する要素を削除

とやろうとしたものの、ソートの時点でアホみたいに時間がかかりどのみちできなかった

解法は、高橋君青木君を別々に考えるのではなく、まずは青木君が全部食べてしまうと仮定して(鶴亀算っぽい)総和を

X = -(b_1+b_2+......b_n)

として、そこから高橋君が選択的にk個(これは偶奇による)食べていくと、そのたびにa_i+b_iが加算されるということから、結局a_i+b_iをソートして、大きい方からk個食べた(Xに加算した)と気がXを最大化できる、という風に考える

賢いね むかつく

 

ARC091D

 

わからず 数学ができない

bを固定して考える aをbでわった余りがK以上になるのをaが0~Nの範囲で求めればよい

N = pb+q (q<b) とあらわせるとすると、aを0~Nの範囲で動かしたとき、aをbで割った余りは 0,1,2......b-1というのがp回繰り返された後で(今のはa = 0 ~ bpをbで割った余り)、1,2......qで終了する

この中で余りがK以上になるのは、p回の繰り返しの中ではp*max(0,(b-K))個、残りの1~qではmax(0,(q-K-1))個ある  (maxで0との比較をしたのはbがKより小さくなる場合を除くため)

つまり、一般的なbに対して、条件を満たす組がp*max(0,(b-K))+max(0,(q-K-1))個存在することが分かったので、これをb=1からb=Nまで足し、最後にa = 0の場合を除けばよい

a = 0ではbで割った余りが0で、Kが0でなければ引く必要性はなく、Kが0の場合はp回余計にカウントされてしまっているので、求めた値からN*pを除けば(bが1~Nをカウントした分)よい

賢いね むかつく むかつく

 

 

 ABCのAを全部解き切りました めでたい

 

SS

エッチなのを投稿した Pixiv R-18ランキングで7位になり笑顔