1
2

More than 1 year has passed since last update.

AtCoder Beginner Contest 259 参戦記

Last updated at Posted at 2022-07-10

AtCoder Beginner Contest 259 参戦記

ABC259A - Growth Record

2分半で突破. 書くだけ.

N, M, X, T, D = map(int, input().split())

print(T - (X - min(X, M)) * D)

ABC259B - Counterclockwise Rotation

19分で突破、WA1. 回転の公式を使えば一発.

from math import radians, cos, sin

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

theata = radians(d)
print(a * cos(theata) - b * sin(theata), a * sin(theata) + b * cos(theata))

角度を求めても良いけど、求めるときに acos, asin を使ってはダメ(WAの理由).

from math import hypot, atan2, radians, cos, sin

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

r = hypot(a, b)
theta = atan2(b, a) + radians(d)
print(cos(theta) * r, sin(theta) * r)

ABC259C - XX to XXX

9分半で突破. 色々考えると文字とその連続数の組のストリームに変換するのが楽だと分かる.

def encode_runlength(s):
    result = []
    p = s[0]
    a = 1
    for c in s[1:]:
        if p == c:
            a += 1
            continue
        result.append((p, a))
        p = c
        a = 1
    result.append((p, a))
    return result

S = input()
T = input()

s = encode_runlength(S)
t = encode_runlength(T)

if len(s) != len(t):
    print('No')
    exit()

for (c0, a0), (c1, a1) in zip(s, t):
    if c0 != c1:
        print('No')
        exit()
    if a0 >= 2 and a1 > a0:
        a0 = a1
    if a0 != a1:
        print('No')
        exit()
print('Yes')

ABC259D - Circumferences

27分で突破. $N \le 3000$ なので全ての組み合わせでも $ {}_ {3000}\mathrm{C}_{2} \fallingdotseq 4.5 \times 10^6$ となりすべての組み合わせで交差判定することができる. 交差判定で得た接続情報は UnionFind で管理するのが一番楽. 後はググって交差判定のコードを書くだけ.

from sys import setrecursionlimit, stdin


def find(parent, i):
    t = parent[i]
    if t < 0:
        return i
    t = find(parent, t)
    parent[i] = t
    return t


def unite(parent, i, j):
    i = find(parent, i)
    j = find(parent, j)
    if i == j:
        return
    parent[j] += parent[i]
    parent[i] = j


readline = stdin.readline
setrecursionlimit(10 ** 6)


def intersect(c1, c2):
    (x1, y1, r1), (x2, y2, r2) = c1, c2
    d = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)
    return d >= (r1 - r2) * (r1 - r2) and d <= (r1 + r2) * (r1 + r2)


def on_circle(x1, y1, c):
    x2, y2, r = c
    return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) == r * r


N = int(readline())
sx, sy, tx, ty = map(int, readline().split())
xyr = [list(map(int, readline().split())) for _ in range(N)]

parent = [-1] * (N + 1)

for i in range(N - 1):
    for j in range(i + 1, N):
        if intersect(xyr[i], xyr[j]):
            unite(parent, i, j)

for i in range(N):
    if on_circle(sx, sy, xyr[i]):
        a = i
    if on_circle(tx, ty, xyr[i]):
        b = i

if find(parent, a) == find(parent, b):
    print('Yes')
else:
    print('No')

ABC259E - LCM on Whiteboard

31分で突破、WA1. 最小公倍数が変化するのはある $p$ に対して $a_i$ が最大の $e$ を単独で持っているときだけ. なので $p$ 毎に最大の $e$ がいくつで、それを持っている $a_i$ が一つだけなのかの情報を収集すれば、その $a_i$ を1にしたときに最小公倍数が変化するのかが分かる. 変化した場合、単独で持っているという条件より、同じ最小公倍数に変化することは、他の $a_i$ を1にしても発生しないため、1にすると最小公倍数が変化する $a_i$ の数を求めると答えが得られる.

from sys import stdin

readline = stdin.readline

N = int(readline())

a = []
maxe = {}
unique = {}

for _ in range(N):
    m = int(readline())
    d = {}
    for _ in range(m):
        p, e = map(int, readline().split())
        d[p] = e
        maxe.setdefault(p, 0)
        if e > maxe[p]:
            maxe[p] = e
            unique[p] = True
        elif e == maxe[p]:
            unique[p] = False
    a.append(d)

changes = 0
for d in a:
    for p in d:
        if d[p] == maxe[p] and unique[p]:
            changes += 1
            break
nochanges = N - changes
print(changes + min(1, nochanges))
1
2
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
2