1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

AtCoder Beginner Contest 166の復習, E問まで(Python)

Posted at

競プロ初心者の復習用記事です。

ここで書く解は解説や他の人の提出を見ながら書いたものです。自分が実際に提出したものとは限りません。

今回の敗因

あっ、日曜もやってたんだ?

コンテストの存在を知らなかった。日程を見てなかった。
というわけで、コンテスト終了後に問題を解いてます。

A - A?C

atcoder社は毎週土曜日にコンテストを開催しているそうです。次回はABCとARCのどちらが開催されるか答える問題です。

入力が'ABC'なら'ARC'を出力。違ったら'ABC'を出力しましょう。

S = input()
if S == 'ABC':
  print('ARC')
else:
  print('ABC')

B - Trick or Treat

K種類のお菓子がそれぞれ番号$\boldsymbol{A_k}$の子供に配られます。お菓子を受け取っていない子供は何人いるか答える問題です。

それぞれの配列の要素を合わせて重複を取り除き、「お菓子が配られた人数」を調べて全体の人数から引けばいいと思います。

N, K = map(int, input().split())
A = []
for _ in range(K):
  d = input()
  A += list(map(int, input().split()))
print(N - len(set(A)))

↓は毎回set型に突っ込んでみたパターン。こっちの方が早かった。

N, K = map(int, input().split())
A = set()
for _ in range(K):
  d = input()
  A = A.union(set(map(int, input().split())))
print(N - len(A))

C - Peaks

「自身と隣接している全ての展望台より高い」という条件を満たしている展望台が何個あるか答える問題です。

グラフ問題...のように見えますが、そんなに難しいことを考える必要はないでしょう。隣接した展望台が自分以上の高さを持つならFalse。持たないならTrue。最後にTrueの数を調べて出力しました。

「同じ高さ」を持つ展望台は共にFalseなことに注意。

N, M = map(int, input().split())
H = list(map(int, input().split()))

good = [True] * N

for _ in range(M):
  A, B = map(int, input().split())
  A -= 1
  B -= 1
  if H[A] >= H[B]:
    good[B] = False
  if H[A] <= H[B]:
    good[A] = False
print(sum(good))

D - I hate Factorization

$$ A^5 - B^5 = X $$
を満たす整数の組(A, B)を一つ出力する問題です。

$X \leq 10^9$という制限を満たすための$A, B$はどのくらい範囲を取ればいいのでしょうか。5乗して$10^9$を超える数は?

n = 1
while n**5 < 10**9:
  n += 1
print(n)
# 64

適当にこの倍ほど範囲を取って全探索してみます。

import itertools

X = int(input())

for a, b in itertools.product(range(128), range(-128, 128)):
  if(a ** 5 - b ** 5 == X):
    print(a, b)
    break

通っちゃいました。

解説を見たところ、

$$ n^5 - (n-1)^5 \geq 10^9 $$
を満たす$n$,つまり$n=120$までを探索する...と考えるのが正しいようです。結果オーライですがちゃんと考えるようにしましょう。あとはこの計算が通る限り、できるだけ広い範囲を探索しちゃうのも手ですね。

E - This Message Will Self-Destruct in 5s

「このメッセージは5秒後に自動的に消滅する」。

$A_i + A_j = j-i$を満たす数を答える問題です。

itertools.combinations_with_replacement()で全網羅しました。TLEになりました。

import itertools

N = int(input())
A = list(map(int, input().split()))

count = sum([j-i == A[i-1]+A[j-1] for i, j in itertools.combinations_with_replacement(range(1, N+1), 2)])

print(count)

わからなくてギブアップ。解説を見ます。$O(n^2)$から逃れることはできるんでしょうか?

$$ A_i + A_j = j-i $$
$$ ↓ $$
$$A_i + i = j-A_j $$

できました。それぞれの値について独立なステータスを計算すればいいと。

値$A_i$に対して、$L_i = i + A_i$, $R_i = i - A_i$という値を計算します。$R$と$L$にそれぞれどの値が何個入っているのか数えれば$L_i = R_j$となる組み合わせの数を計算できます。

というわけで以下のコードで実装しました。

import collections

N = int(input())
A = list(map(int, input().split()))

L = [i + A[i] for i in range(N)]
R = [i - A[i] for i in range(N)]

countL = collections.Counter(L)
countR = collections.Counter(R)

print(sum([countL[n] * countR[n] for n in countL.keys()]))

この記事はここまでとします。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?