🧩 Problem Solving/[λ°±μ€€]

[λ°±μ€€] 28298 더 ν”ν•œ 타일 색칠 문제 (python 파이썬)

μ œλ΄‰μ•„ 2023. 7. 4. 17:12

https://www.acmicpc.net/problem/28298

 

28298번: 더 ν”ν•œ 타일 색칠 문제

첫째 쀄에 μ„Έ μ •μˆ˜ $N$, $M$, $K$κ°€ 곡백으둜 κ΅¬λΆ„λ˜μ–΄ 주어진닀. $(1\le N,M,K\le 500;$ $N,M$은 $K$의 λ°°μˆ˜μ΄λ‹€$)$ λ‹€μŒ $N$개의 μ€„μ—λŠ” νƒ€μΌμ˜ $i$ν–‰ 색상 배치λ₯Ό μ˜λ―Έν•˜λŠ” 길이 $M$의 λ¬Έμžμ—΄ $d_i$κ°€ 주어진닀.

www.acmicpc.net


μ‹œκ°„ μ΄ˆκ³Όκ°€ 생긴 문제. μ΄λ²ˆμ—” μž…λ ₯κ°’ μ œν•œμ„ 보고 μ‹œκ°„μ— 맞게 λ‘œμ§μ„ μ§°λ‹€κ³  μƒκ°ν–ˆλŠ”λ° μ‹œκ°„μ΄ˆκ³Όκ°€ λ°œμƒν–ˆλ‹€.

λ‘œμ§μ„ 쑰금 μˆ˜μ •ν•˜λ‹ˆκΉŒ ν†΅κ³Όν–ˆλ‹€. μ™œ κ·ΈλŸ°μ§€ 생각해 λ³΄λ‹ˆ 원인을 찾을 수 μžˆμ—ˆλ‹€.

 

쀑간에 λ¦¬μŠ€νŠΈμ—μ„œ κ°œμˆ˜κ°€ κ°€μž₯ λ§Žμ€ μš”μ†Œλ₯Ό 좜λ ₯ν•˜λŠ” λ©”μ„œλ“œκ°€ ν•„μš”ν–ˆλ‹€.

λ§Žμ€ 방법이 μžˆμ§€λ§Œ λ‚˜λŠ” μ½”λ“œλ₯Ό κ°„κ²°ν•˜κ²Œ μž‘μ„±ν•˜κ³  μ‹Άμ–΄ max(arr, key = arr.count)둜 κ΅¬ν˜„ν–ˆλ‹€.

len(arr) = n이라 κ°€μ •ν•˜λ©΄, arr.count κ°€ n번 μ‹€ν–‰λœλ‹€. λ”°λΌμ„œ μœ„ μ½”λ“œμ˜ μ‹œκ°„λ³΅μž‘λ„λŠ” n**2이닀.

 

λ”°λΌμ„œ 전체 μ‹œκ°„λ³΅μž‘λ„λŠ” μ•½ K * K * ((N/K * M/K )**2)이고 μ΅œλŒ€ 1 * 1 * ((500 * 500)**2) = 62500000000이 λœλ‹€. μ‹œκ°„μ΄ˆκ³Όλ‚˜ λ°œμƒν•˜λŠ” 게 λ‹Ήμ—°ν•˜λ‹€.

 

였늘의 κ΅ν›ˆ: μƒˆλ‘œμš΄ 방법을 μ“Έ λ•ŒλŠ” μ‹œκ°„λ³΅μž‘λ„λ₯Ό 꼼꼼히 계산해 보자.


아이디어

1. K * K둜 타일듀을 λ‚˜λˆ μ€€λ‹€.

2. μœ„μ— λΉ¨κ°„μƒ‰μ²˜λŸΌ, K * K둜 λ‚˜λˆ μ§„ νƒ€μΌλ“€μ˜ 각 자리λ₯Ό κΈ°μ€€μœΌλ‘œ μ•ŒνŒŒλ²³ 개수λ₯Ό κ³„μ‚°ν•œλ‹€.

3. μ•ŒνŒŒλ²³ κ°œμˆ˜κ°€ κ°€μž₯ λ§Žμ€ μ•ŒνŒŒλ²³μœΌλ‘œ 타일듀을 ꡐ체해 μ€€λ‹€. κ΅μ²΄ν•œ 타일 κ°œμˆ˜λ„ μ €μž₯ν•΄ μ€€λ‹€.


전체 μ½”λ“œ (+ 주석) 

import sys

tiles = [] # N * M 타일
count_list = [0] * 26 # μ•ŒνŒŒλ²³μ˜ 개수λ₯Ό countν•΄μ£ΌλŠ” 리슀트
Sum = 0 # κ΅μ²΄ν•œ 타일 개수

N, M, K = map(int, input().split())
for i in range(N):
    tiles.append(list(sys.stdin.readline().rstrip()))

step_num = N * M // K**2 # K * K 둜 λ‚˜λˆˆ 개수

for x in range(K):
    for y in range(K): # K * K νŒμ—μ„œ 각각의 자리

        count_list = [0] * 26 # 개수 count 리슀트 μ΄ˆκΈ°ν™”

        for i in range(0, N - K+ 1, K):
            for j in range(0, M - K + 1, K): 
                t = tiles[i + x][j + y]
                count_list[ord(t) - 65] += 1 # μ•ŒνŒŒλ²³ count

        max_tile_num = max(count_list) 
        Sum += step_num - max_tile_num # λ³€κ²½ν•œ 타일 개수 μΆ”κ°€
        max_tile = chr(count_list.index(max_tile_num) + 65) #κ°€μž₯ κ°œμˆ˜κ°€ λ§Žμ€ μ•ŒνŒŒλ²³ return

        for i in range(0, N - K+ 1, K):
            for j in range(0, M - K + 1, K):
                tiles[i + x][j + y] = max_tile # 타일 λ³€ν™˜

# 좜λ ₯
print(Sum)
for line in tiles:
    print("".join(line))

μ½”λ“œ μ„€λͺ…

count_list = [0] * 26 # 개수 count 리슀트 μ΄ˆκΈ°ν™”

for i in range(0, N - K+ 1, K):
    for j in range(0, M - K + 1, K):
        t = tiles[i + x][j + y]
        count_list[ord(t) - 65] += 1 # μ•ŒνŒŒλ²³ count

타일에 올 수 μžˆλŠ” 값이 μ•ŒνŒŒλ²³ λŒ€λ¬Έμžλ§Œ 올 수 μžˆλ‹€λŠ” κ±Έ μ΄μš©ν•΄ 각 μ•ŒνŒŒλ²³μ˜ 개수λ₯Ό λ°°μ—΄μ˜ κ°’μœΌλ‘œ ν‘œν˜„ν–ˆλ‹€. 

ord() ν•¨μˆ˜λ₯Ό ν™œμš©ν•΄ μΈλ±μŠ€κ°’κ³Ό μ•ŒνŒŒλ²³μ„ μΌμΉ˜μ‹œμΌœμ€€λ‹€. (ord('A') = 65, chr(65) = 'A')

 

max_tile_num = max(count_list)
Sum += step_num - max_tile_num # λ³€κ²½ν•œ 타일 개수 μΆ”κ°€
max_tile = chr(count_list.index(max_tile_num) + 65) #κ°€μž₯ κ°œμˆ˜κ°€ λ§Žμ€ μ•ŒνŒŒλ²³ return

for i in range(0, N - K+ 1, K):
    for j in range(0, M - K + 1, K):
        tiles[i + x][j + y] = max_tile # 타일 λ³€ν™˜

κ°€μž₯ λ§Žμ€ μ•ŒνŒŒλ²³μ˜ 개수λ₯Ό μ΄μš©ν•΄ λ³€κ²½ν•œ 타일 개수λ₯Ό κ΅¬ν•œλ‹€.

chr() ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•΄μ„œ μ•ŒνŒŒλ²³μ„ 리턴해쀀닀.