/ WOJ / 讨论 / 题解 /

C_Dreamer_ZW金名快乐!!!

To solve this problem, we need to determine the maximum number of unburned forest sections after strategically placing a fire barrier (isolation zone) in a circular forest. The fire spreads from initially burning sections to adjacent sections every minute, and the barrier prevents the fire from spreading through that section. The goal is to place the barrier such that after a given time ( t_0 ), the number of unburned sections is maximized.

Approach

  1. Problem Analysis: The forest is circular, divided into ( n ) sections. Some sections are initially on fire. The fire spreads to adjacent sections every minute. We can place a barrier at one initially unburned section at time 0. The barrier prevents fire from spreading through it. After ( t_0 ) minutes, we need to find the maximum number of sections that remain unburned.

  2. Key Insight: Placing the barrier splits the circular forest into a linear chain. The fire spreads from each initially burning section in both directions along the chain but stops at the barrier. The unburned sections are those not reached by the fire within ( t_0 ) minutes.

  3. Algorithm Selection:

    • Preprocessing: Identify all initially burning sections and candidate barrier positions (initially unburned sections).
    • Handling Fire Spread: For each candidate barrier position, simulate the fire spread along the linear chain formed by removing the barrier. The spread is limited by ( t_0 ) minutes and the barrier.
    • Calculating Unburned Sections: For each candidate, compute the number of sections not reached by the fire. This involves:
      • Left and Right Ends: Sections beyond ( t_0 ) steps from the nearest burning section at the ends of the chain.
      • Gaps Between Fires: Sections between two fires that are more than ( 2t_0 + 1 ) units apart, ensuring the fire doesn't cover the entire gap.
    • Efficiency: Use binary search to efficiently determine the nearest burning sections relative to each candidate barrier, allowing the solution to handle large inputs within constraints.
  4. Complexity Analysis:

    • Time Complexity: For each test case, processing involves ( O(n \log k) ) operations, where ( k ) is the number of initially burning sections. The total across all test cases is ( O(\sum n \log k) ), which is efficient given the constraints.
    • Space Complexity: ( O(n) ) per test case to store the positions of burning sections and candidates.

Solution Code

import bisect

t = int(input().strip())
for _ in range(t):
    n, t0 = map(int, input().split())
    s = input().strip()
    F = [i for i in range(n) if s[i] == '1']
    candidates = [i for i in range(n) if s[i] == '0']
    
    if not F:
        print(0)
        continue
        
    F.sort()
    within_total = 0
    for i in range(len(F) - 1):
        gap = F[i+1] - F[i] - 2*t0 - 1
        if gap > 0:
            within_total += gap
            
    between_all = n - (F[-1] - F[0]) - 2*t0 - 1
    if between_all < 0:
        between_all = 0
        
    ans = 0
    if not candidates:
        print(0)
        continue
        
    for B in candidates:
        pos = bisect.bisect_right(F, B)
        has_first = (pos < len(F))
        has_second = (pos > 0)
        
        if has_first and has_second:
            term = F[pos] - F[pos-1] - 2*t0 - 1
            if term < 0:
                term = 0
            within = within_total - term
        else:
            within = within_total
            
        between = between_all if (has_first and has_second) else 0
        
        if has_first:
            A0 = F[pos] - B - 1
        elif has_second:
            A0 = n + F[0] - B - 1
        else:
            A0 = 0
        left_val = A0 - t0
        if left_val < 0:
            left_val = 0
            
        if has_second:
            last = n + F[pos-1] - B - 1
        elif has_first:
            last = F[-1] - B - 1
        else:
            last = 0
        right_val = (n - 2) - (last + t0)
        if right_val < 0:
            right_val = 0
            
        unburned = left_val + right_val + between + within
        if unburned > ans:
            ans = unburned
            
    print(ans)

Explanation

  1. Input Handling: The number of test cases ( t ) is read first. For each test case, the number of sections ( n ) and time ( t_0 ) are read, followed by the initial fire status string ( s ).
  2. Initial Setup: The positions of initially burning sections (( F )) and candidate barrier positions (sections with '0') are identified.
  3. Preprocessing:
    • Within Total: Computes the sum of gaps between consecutive burning sections that are larger than ( 2t_0 + 1 ), indicating sections that remain unburned between fires.
    • Between All: Computes potential unburned sections if the barrier separates the farthest burning sections.
  4. Candidate Evaluation: For each candidate barrier position:
    • Binary Search: Determines the nearest burning sections to the barrier using binary search.
    • Unburned Calculation:
      • Left and Right Ends: Sections beyond ( t_0 ) steps from the first or last burning section in the chain.
      • Gaps: Unburned sections between fires not covered within ( t_0 ) steps.
  5. Result Output: The maximum unburned sections across all candidates is printed for each test case.

This approach efficiently leverages binary search and preprocessing to handle the constraints, ensuring optimal barrier placement for maximum unburned sections.

0 条评论

目前还没有评论...