1
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?

C - Merge the balls

問題

考えたこと

実際に$2^x$を格納して探索していくとTLEやMLEになってしまいます。よって、指数部分だけを考え、条件3については$2^x + 2^x = 2^{(x+1)}$となる性質を使います。ほかの条件は素直に実装すればOKです。

ACコード

c.py
n = int(input())
A = list(map(int, input().split()))

ans = []

for i in range(n):
    ans.append(A[i])
    while True:
        if len(ans) <= 1:
            break
        elif ans[-1] != ans[-2]:
            break
        else:
            ans.pop()
            ans.append(ans.pop() + 1)

print(len(ans))

D - Grid and Magnet

問題

考えたこと

流れとしてはABC349のD問題と同じように、与えられた文字列を自分が探索しやすいようにグラフ化し、探索という方針です。ただし、以下の二点に注意しつつ有向グラフを作成します。

  • 磁石自身と磁石が隣り合うところからスタートできない
  • 各頂点の番号が$i*w + j$と表される

image.png

また、図を眺めてみると以下の点に気が付きます。

  • 磁石が隣りにない頂点同士の自由度は等しい
    • 行き来できるので自由度を共有する
  • 頂点6は二つの頂点から行先として指定されている
    • BFSでは訪問済みの点をチェックしておくが、チェック方法を工夫しておく必要がある

以上の気づきから、訪問済みの点は再訪問する必要ない、訪問済みの頂点のチェック方法として以前訪問した頂点の情報を格納する、という方法をとることとしました。

ACコード

d.py
from collections import defaultdict, deque

h, w = map(int, input().split())
s = [input() for _ in range(h)]
g = defaultdict(set)
dij = [(-1, 0), (1, 0), (0, -1), (0, 1)]

# グラフの作成
for i in range(h):
    for j in range(w):
        if s[i][j] == "#":
            continue
        u = i * w + j
        mag = False
        # 注目している頂点の四方向に磁石があるならばスキップ
        for di, dj in dij:
            nex_i, nex_j = i + di, j + dj
            if not (0 <= nex_i < h and 0 <= nex_j < w):
                continue
            if s[nex_i][nex_j] == "#":
                mag = True
        if mag:
            continue
        # 注目している頂点の四方向に磁石がないならば辺を張る
        for di, dj in dij:
            nex_i, nex_j = i + di, j + dj
            if not (0 <= nex_i < h and 0 <= nex_j < w):
                continue
            v = nex_i * w + nex_j
            g[u].add(v)

vis = [-1 for _ in range(h * w)]
ans = 0

for i in range(h):
    for j in range(w):
        # st: 始点となる点
        st = i * w + j
        if s[i][j] == "#" or vis[st] != -1:
            continue
        que = deque([st])
        free = 0  # 自由度
        # BFS
        while que:
            pos = que.pop()
            if vis[pos] == st:
                continue
            vis[pos] = st  # 訪問先として現在探索している頂点を格納する
            free += 1
            for to in g[pos]:
                que.appendleft(to)
        ans = max(ans, free)

print(ans)
1
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
1
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?