QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#667639#2955. Stable Tablevic233333TL 365ms72436kbPython34.3kb2024-10-23 01:16:332024-10-23 01:16:33

Judging History

你现在查看的是最新测评结果

  • [2024-10-23 01:16:33]
  • 评测
  • 测评结果:TL
  • 用时:365ms
  • 内存:72436kb
  • [2024-10-23 01:16:33]
  • 提交

answer

from collections import defaultdict, deque
from typing import List, Set, Dict, Tuple

def get_piece_coords(grid: List[List[int]], piece_num: int) -> Set[Tuple[int, int]]:
    """Get all coordinates for a given piece number."""
    coords = set()
    for i in range(len(grid)):
        for j in range(len(grid[0])):
            if grid[i][j] == piece_num:
                coords.add((i, j))
    return coords

def get_all_pieces(grid: List[List[int]]) -> Set[int]:
    """Get set of all piece numbers in the grid."""
    pieces = set()
    for row in grid:
        pieces.update(row)
    return pieces

def get_top_pieces(grid: List[List[int]]) -> Set[int]:
    """Get pieces that form the top surface."""
    return set(grid[0])

def is_on_floor(coords: Set[Tuple[int, int]], height: int) -> bool:
    """Check if piece touches the floor."""
    return any(i == height-1 for i, j in coords)

def has_stable_support(piece_coords: Set[Tuple[int, int]], 
                      supporting_pieces: Dict[int, Set[Tuple[int, int]]], 
                      height: int) -> bool:
    """
    Check if a piece has stable support either from floor or other pieces.
    A piece needs horizontal edge contact (positive area) for stability.
    """
    # Check floor contact
    if is_on_floor(piece_coords, height):
        return True
        
    # Check support from other pieces
    piece_bottom_edges = {(i,j) for i,j in piece_coords if (i+1,j) not in piece_coords}
    
    for support_coords in supporting_pieces.values():
        support_top_edges = {(i,j) for i,j in support_coords if (i-1,j) not in support_coords}
        
        # Check for horizontal edge overlap (positive area contact)
        for i, j in piece_bottom_edges:
            if (i+1, j) in support_top_edges:
                return True
                
    return False

def is_configuration_stable(pieces: Set[int], grid: List[List[int]], 
                          piece_coords: Dict[int, Set[Tuple[int, int]]], 
                          height: int) -> bool:
    """Check if a given configuration of pieces forms a stable table."""
    # Must include all top pieces
    top_pieces = get_top_pieces(grid)
    if not top_pieces.issubset(pieces):
        return False
    
    # Top pieces must form at most two pieces
    if len(top_pieces - (top_pieces - pieces)) > 2:
        return False
        
    # Check stability of each piece
    stable_pieces = set()
    
    while True:
        found_stable = False
        for piece in pieces - stable_pieces:
            if has_stable_support(piece_coords[piece], 
                                {p: piece_coords[p] for p in stable_pieces}, 
                                height):
                stable_pieces.add(piece)
                found_stable = True
                
        if not found_stable:
            break
            
    return stable_pieces == pieces

def solve(height: int, width: int, grid: List[List[int]]) -> int:
    """Find minimum number of pieces needed for a stable table."""
    all_pieces = get_all_pieces(grid)
    piece_coords = {p: get_piece_coords(grid, p) for p in all_pieces}
    
    # Start with minimum required pieces (top pieces)
    min_pieces = float('inf')
    top_pieces = get_top_pieces(grid)
    
    # Try all possible combinations of pieces
    queue = deque([(top_pieces, set())])
    seen = set()
    
    while queue:
        required, optional = queue.popleft()
        current = required | optional
        
        # Skip if we've seen this combination or it's larger than current minimum
        if tuple(sorted(current)) in seen or len(current) >= min_pieces:
            continue
        seen.add(tuple(sorted(current)))
        
        # Check if current configuration is stable
        if is_configuration_stable(current, grid, piece_coords, height):
            min_pieces = min(min_pieces, len(current))
            continue
            
        # Try adding each remaining piece
        remaining = all_pieces - current
        for piece in remaining:
            queue.append((required, optional | {piece}))
            
    return min_pieces

# Process input
h, w = map(int, input().split())
grid = []
for _ in range(h):
    grid.append(list(map(int, input().split())))
    
print(solve(h, w, grid))

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 31ms
memory: 12252kb

input:

7 8
3 3 3 3 10 10 10 10
2 14 3 7 7 10 4 11
2 14 3 1 1 10 4 11
2 14 8 8 8 8 4 11
9 14 5 5 5 5 4 13
9 14 12 12 12 12 4 13
9 6 6 6 6 6 6 13

output:

5

result:

ok single line: '5'

Test #2:

score: 0
Accepted
time: 23ms
memory: 12020kb

input:

8 8
1 1 1 1 1 1 1 1
2 3 3 4 5 6 6 7
2 2 3 4 5 6 7 7
2 3 3 3 6 6 6 7
2 2 3 8 8 8 6 7
9 2 9 10 10 11 11 12
9 9 9 9 10 11 12 12
13 9 14 14 10 10 15 15

output:

3

result:

ok single line: '3'

Test #3:

score: 0
Accepted
time: 28ms
memory: 13228kb

input:

10 10
1 1 1 1 1 1 1 1 1 1
1 2 2 2 2 2 2 2 2 2
1 1 1 1 1 1 1 1 1 2
3 4 5 6 7 8 9 10 11 2
12 13 5 6 7 7 7 7 2 2
14 15 5 6 6 6 6 7 16 16
14 15 15 15 6 16 16 16 16 16
14 14 14 15 16 16 17 16 18 19
15 15 15 15 20 20 20 20 18 19
20 20 20 20 20 21 21 21 21 19

output:

4

result:

ok single line: '4'

Test #4:

score: 0
Accepted
time: 365ms
memory: 72436kb

input:

10 8
20 20 20 20 16 16 16 16
18 19 1 3 3 21 17 2
18 19 1 4 4 21 17 2
18 19 1 5 5 21 17 2
18 19 6 6 6 6 17 2
18 7 7 7 7 7 7 2
18 8 8 8 8 8 8 8
9 9 9 9 9 9 11 11
14 14 9 9 9 9 12 12
15 15 10 10 10 10 13 13

output:

7

result:

ok single line: '7'

Test #5:

score: 0
Accepted
time: 62ms
memory: 17536kb

input:

10 5
4 4 4 2 2
4 4 4 8 8
15 4 1 1 8
3 4 9 9 9
3 6 6 6 6
3 13 13 12 12
3 10 10 12 12
3 14 14 7 7
11 11 11 7 7
5 5 5 7 7

output:

7

result:

ok single line: '7'

Test #6:

score: 0
Accepted
time: 89ms
memory: 18708kb

input:

10 5
4 4 4 2 2
4 4 4 8 8
15 4 1 1 8
3 4 9 9 9
3 4 6 6 6
3 13 13 12 12
3 10 10 12 12
3 14 14 7 7
11 11 11 7 7
5 5 5 7 7

output:

8

result:

ok single line: '8'

Test #7:

score: -100
Time Limit Exceeded

input:

10 10
1 1 1 1 1 1 1 1 1 1
2 2 3 1 1 1 1 1 4 4
2 2 5 6 7 1 1 8 9 9
2 2 10 11 12 13 14 8 9 9
15 15 16 17 18 13 14 14 19 19
20 20 16 21 22 23 23 23 24 24
25 26 21 21 27 28 28 29 30 30
31 32 21 33 34 34 35 36 37 38
39 40 21 41 41 42 42 43 43 43
44 40 45 46 47 48 49 50 51 43

output:


result: