公式

A - カードバトル / Card Battle 解説 by admin

GPT 5.2 High

Overview

This problem asks you to process pairs of cards with adjacent numbers \((i, i+1)\) in order from \(i=1\), exactly once each, simulating the operation where cards are absorbed (removed) and attack power increases, then counting how many cards remain at the end.

Analysis

The key insight is that “the pairs to process are cards numbered \(i\) and \(i+1\), not cards that are physically adjacent.” In other words, even if cards are removed along the way, the next comparison partner does not slide to the “nearest surviving neighbor.”

Because of this, for each \(i\), all we need to check is “are card \(i\) and card \(i+1\) still alive?” and “if so, what are their current attack powers?” Since processing occurs exactly once for each \(i=1,2,\dots,N-1\) in one direction:

  • Card \(i\)’s attack power can only change during the previous processing \((i-1,i)\) (where \(i\) absorbed or was absorbed) and the current processing \((i,i+1)\)
  • Therefore, a single left-to-right pass through the array is sufficient

If you mistakenly assume that “the adjacency relationships among surviving cards change,” you might be tempted to implement something with a linked list or Union-Find to find “the next surviving card,” but this is unnecessary for this problem (and in fact tends to make the implementation more complex). All that’s needed is updating a “survival flag” and an “attack power array.”

Algorithm

We directly simulate the following:

  1. Maintain an array A[i] holding card \(i\)’s current attack power (updated upon absorption).
  2. Prepare an array alive[i] (survival flag), initialized to alive for all cards.
  3. Process in order from \(i=1\) to \(N-1\) (in 0-indexed implementation, i=0..N-2):
    • If alive[i] or alive[i+1] is 0 (dead), do nothing
    • If both are alive, compare attack powers:
      • Equal: do nothing
      • \(A[i] > A[i+1]\): card \(i\) absorbs
        alive[i+1]=0, A[i] = A[i] + floor(A[i+1]/2)
      • \(A[i] < A[i+1]\): card \(i+1\) absorbs
        alive[i]=0, A[i+1] = A[i+1] + floor(A[i]/2)
  4. Finally, count the number of 1s in alive and output it.

Concrete Example

For \(A=[10, 6, 20]\): - \(i=1\) (cards 1 and 2): \(10>6\), so card 1 absorbs card 2
Card 2 is eliminated, card 1’s attack power becomes \(10+\lfloor 6/2\rfloor=13\) - \(i=2\) (cards 2 and 3): Card 2 is already gone, so nothing happens
The final result is 2 cards remaining: cards 1 and 3.

Complexity

  • Time complexity: \(O(N)\) (each pair is examined exactly once)
  • Space complexity: \(O(N)\) (attack power array and survival flags)

Implementation Notes

  • Since \(N \le 10^6\), input/output can become a bottleneck in Python. The code uses sys.stdin.buffer.read() with a custom parser to read integers quickly.

  • The survival flag uses a bytearray to save memory, and the final count is obtained with alive.count(1).

  • The attack power update after absorption is always + (opponent // 2) (floor division). Note that the attack power is updated and used in subsequent comparisons.

    Source Code

import sys

data = sys.stdin.buffer.read()
L = len(data)
p = 0

def readint():
    global p
    while p < L and data[p] <= 32:
        p += 1
    num = 0
    while p < L and data[p] > 32:
        num = num * 10 + (data[p] - 48)
        p += 1
    return num

N = readint()
A = [0] * N
for i in range(N):
    A[i] = readint()

alive = bytearray(b"\x01") * N

for i in range(N - 1):
    if alive[i] and alive[i + 1]:
        ai = A[i]
        aj = A[i + 1]
        if ai > aj:
            alive[i + 1] = 0
            A[i] = ai + (aj // 2)
        elif ai < aj:
            alive[i] = 0
            A[i + 1] = aj + (ai // 2)

sys.stdout.write(str(alive.count(1)) + "\n")

This editorial was generated by gpt-5.2-high.

投稿日時:
最終更新: