알고리즘 문제풀이

[백준 3085] 사탕 게임 (Swift)

SiO2whocode 2025. 2. 12. 21:44
728x90

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

 

브루트포스

아래와 같은 N*N 행렬에 사탕들이 종류별로 채워져 있음 -> 여기서 인접한 두개의 서로 다른 사탕을 서로 바꿨을 때,

행 또는 열에(가로 혹은 세로로) 가능한 긴 연속된 사탕의 개수가 뭔지 출력하는 문제이다.

CCP
CCP
PPC

 

접근방법

1. 초기 상태에서 가장 긴 연속 사탕 수 구하기 (BFS로 할 수 있을 것 같긴 한데..그냥 칸마다 구했습니다! (당당))

2. 바꿀 수 있는 두 캔디 찾기 (인접하면서 서로 다른 캔디 쌍)

3. 두 캔디 위치를 바꿨을 때 (swap) 두 캔디를 포함하는 가장 긴 연속 캔디 수를 구하고 현재 최대 길이랑 비교해서 갱신

이때, A, B 캔디라고 하면, A캔디 기준으로 가로, 세로로 가장 긴 연속 캔디 수 확인

B 캔디 기준으로 가로, 세로로 가장 긴 연속 캔디 수 확인

4. 그리고 매번 다시 위치 원래대로 되돌려주기

 

오답노트

같은 구조에 변수만 다른 코드를 여러번 쓰다보니까 변수들을 잘 관리하는 게 중요했다. (함수로 추상화 시켰으면 물론 좋았겠지만..^^)

c라고 써야되는걸 r이라고 썼어서 한번 대각선으로 캔디가 뒤바뀌는 경우가 생겼었고..;

원래 같은 행이나 같은 열에 있는 두 캔디의 위치를 바꾸는 거였으면, 두 캔디가 공유하는 행이나 열은 다시 계산하지 않았는데, 

ABAA같은 경우 AB를 서로 바꿨을 때 BAAA가 되면서 최대 길이가 또 갱신되기 때문에, 두 캔디를 기준으로 가로(행), 세로(열) 모두 계산을 다시해줘야 한다.

 

소스코드

import Foundation

func solution() -> Int {
    var result:Int = 0
    var map:[[Character]] = []
    let N:Int = Int(readLine()!) ?? 1
    
    for _ in 0..<N {
        let line:[Character] = Array(String(readLine()!))
        map.append(line)
    }
    
    // 초기 상태에 가장 긴 연속 사탕 수 구하기
    for r in 0..<N {
        for c in 0..<N {
            // r,c start (같은 행)
            var target = map[r][c]
            var cnt = 1
            var cc = c-1 // 옮겨가면서 최대 길이 체크
            while cc >= 0 {
                if map[r][cc] == target {
                    cnt += 1
                    cc -= 1
                } else {
                    break
                }
            }
            cc = c+1
            while cc < N {
                if map[r][cc] == target {
                    cnt += 1
                    cc += 1
                } else {
                    break
                }
            }
            if cnt > result {
                result = cnt
            }
            
            // r,c start (같은 열)
            cnt = 1
            var cr = r-1 // 옮겨가면서 최대 길이 체크
            while cr >= 0 {
                if map[cr][c] == target {
                    cnt += 1
                    cr -= 1
                } else {
                    break
                }
            }
            cr = r+1
            while cr < N {
                if map[cr][c] == target {
                    cnt += 1
                    cr += 1
                } else {
                    break
                }
            }
            if cnt > result {
                result = cnt
            }
        }
    }
    
    let dr = [-1,1,0,0]
    let dc = [0,0,-1,1]
    // process
    // 1. 바꿀 수 있는 두 캔디 찾기
    // 2. 바꿔서 최대 길이 달라지는지 확인
    for r in 0..<N {
        for c in 0..<N {
            // 상하좌우
            for i in 0..<4 {
                let nr = r + dr[i]
                let nc = c + dc[i]
                if nr >= 0 && nr < N && nc >= 0 && nc < N && map[r][c] != map[nr][nc] {
                    // 다른 캔디면 교환하고 최대 길이 갱신
                    // 교환
                    let temp = map[nr][nc]
                    map[nr][nc] = map[r][c]
                    map[r][c] = temp
                    // r,c start
                    // 같은 행
                    var target = map[r][c]
                    var cnt = 1
                    var cc = c-1 // 옮겨가면서 최대 길이 체크
                    while cc >= 0 {
                        if map[r][cc] == target {
                            cnt += 1
                            cc -= 1
                        } else {
                            break
                        }
                    }
                    cc = c+1
                    while cc < N {
                        if map[r][cc] == target {
                            cnt += 1
                            cc += 1
                        } else {
                            break
                        }
                    }
                    if cnt > result {
                        result = cnt
                    }
                    // 같은 열
                    cnt = 1
                    var cr = r-1 // 옮겨가면서 최대 길이 체크
                    while cr >= 0 {
                        if map[cr][c] == target {
                            cnt += 1
                            cr -= 1
                        } else {
                            break
                        }
                    }
                    cr = r+1
                    while cr < N {
                        if map[cr][c] == target {
                            cnt += 1
                            cr += 1
                        } else {
                            break
                        }
                    }
                    if cnt > result {
                        result = cnt
                    }
                    // r,c end
                    
                    // nr,nc start
                    // 같은 행
                    target = map[nr][nc]
                    cnt = 1
                    cc = nc-1 // 옮겨가면서 최대 길이 체크
                    while cc >= 0 {
                        if map[nr][cc] == target {
                            cnt += 1
                            cc -= 1
                        } else {
                            break
                        }
                    }
                    cc = nc+1
                    while cc < N {
                        if map[nr][cc] == target {
                            cnt += 1
                            cc += 1
                        } else {
                            break
                        }
                    }
                    if cnt > result {
                        result = cnt
                    }
                    // 같은 열
                    cnt = 1
                    cr = nr-1 // 옮겨가면서 최대 길이 체크
                    while cr >= 0 {
                        if map[cr][nc] == target {
                            cnt += 1
                            cr -= 1
                        } else {
                            break
                        }
                    }
                    cr = nr+1
                    while cr < N {
                        if map[cr][nc] == target {
                            cnt += 1
                            cr += 1
                        } else {
                            break
                        }
                    }
                    if cnt > result {
                        result = cnt
                    }
                    // nr,nc end
                    
                    // 다시 교환
                    map[r][c] = map[nr][nc]
                    map[nr][nc] = temp
                }
            }
        }
    }
    
    return result
}

print(solution())
728x90