0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Atcoder解法検討】ABC302 A~E Python

Posted at

A - Attack

問題ページ : A - Attack

考察

AをBで割った結果の切り上げ。
切り上げは$(A-1)\ //\ B\ +\ 1$もしくは$(A+B-1)\ //\ B$で求める。

コード

A, B = map(int, input().split())
print((A-1) // B + 1)

B - Find snuke

問題ページ : B - Find snuke

考察

計算量的には余裕があり、バグらないように実装する。
$H \times W$の全マスを起点として全探索。起点から8方向それぞれに5文字分、文字と座標を取り込みます。取り込んだ文字列が"snuke"に一致すれば座標出力。
8方向は移動方向の差分をリストでもっておいてループにとりこむ。
また探索範囲は全マスにしておいて枠外に出る場合はbreakで制限をかけるのが楽。

コード

H, W = map(int, input().split())
M = [input() for _ in range(H)]

ns = list("snuke")
rs = list(reversed(ns))

dr = [(0,-1), (0,1), (1,-1), (1,0), (1,1), (-1,-1), (-1,0), (-1,1)]
for i in range(H):
    for j in range(W):
        for di, dj in dr:
            tmp1 = []
            tmp2 = []
            for k in range(5):
                ni = i + k * di
                nj = j + k * dj
                if not (0 <= ni < H and 0 <= nj < W):break
                tmp1.append(M[ni][nj])
                tmp2.append((ni+1, nj+1))

            if tmp1 == ns:
                for e in tmp2:
                    print(*e)
                exit()

C - Almost Equal

問題ページ : C - Almost Equal

考察

$N \leq 8$なので順列を全探索しても計算量的には問題ない。
itertools.permutationsを使用して順列の全探索。

コード

from itertools import permutations

N, M = map(int, input().split())
S = [input() for _ in range(N)]
P = list(permutations(S))

for p in P:
    is_Yes = True
    for i in range(N-1):
        first = p[i]
        second = p[i+1]
        
        num = 0
        for j in range(M):
            if first[j] != second[j]:
                num += 1
        if num != 1:
            is_Yes = False
            break
    
    if is_Yes:
        print("Yes")
        exit()

print("No")

D - Impartial Gift

問題ページ : D - Impartial Gift

考察

全探索すると$O(MN)$になりTLE。
Aの選択肢によってBの最適選択肢が決定もしくは限定できる場合にbisect(二分探索)を用いるのはある意味典型。

コード

from bisect import bisect_right

N, M, D = map(int, input().split())
A = list(map(int, input().split()))
B = list(map(int, input().split()))
B.sort()

ans = -1

for a in A:
    target_price = a + D
    idx = bisect_right(B, target_price)
    if idx == 0:continue
    b = B[idx-1]
    if abs(a-b) <= D:
        ans = max(ans, a + b)

print(ans)

E - Isolation

問題ページ : E - Isolation

考察

query系の問題はどのようなデータ構造を持つかで対処する場合が多いように思う。
本問題は隣接リストのみを管理することで解は得られるがTLEするケースに遭遇する。
TLEとなる要因は
①隣接リストからの削除が$O(N)$となり得るのでクエリ回数をかけて$O(NQ)$
②孤立している頂点の探索が$O(N)$なのでクエリ回数をかけて$O(NQ)$
これらを解消するために
①隣接リストをlistではなくsetで持つ(setの要素削除は$O(1)$)
②孤立している頂点をsetでもち都度追加・削除をおこないながら要素数を出力(setの追加、削除、要素数カウントはいづれも$O(1)$)

コード

N, q = map(int, input().split())
Q = [tuple(map(int, input().split())) for _ in range(q)]

iso = set(range(N))
G = [set() for _ in range(N)]

for com in Q:
    if com[0] == 1:
        u = com[1] - 1
        v = com[2] - 1
        G[u].add(v)
        G[v].add(u)
        if u in iso:
            iso.remove(u)
        if v in iso:
            iso.remove(v)
        print(len(iso))

    if com[0] == 2:
        u = com[1] - 1
        
        if len(G[u]) == 0:
            print(len(iso))
            continue

        for e in G[u]:
            G[e].remove(u)
            if len(G[e]) == 0:
                iso.add(e)
        
        G[u] = set()
        iso.add(u)

        print(len(iso))

青色diff以上は後日挑戦

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?