안녕하세요!

https://www.acmicpc.net/problem/10026
10026번: 적록색약
적록색약은 빨간색과 초록색의 차이를 거의 느끼지 못한다. 따라서, 적록색약인 사람이 보는 그림은 아닌 사람이 보는 그림과는 좀 다를 수 있다. 크기가 N×N인 그리드의 각 칸에 R(빨강), G(초록)
www.acmicpc.net
간단한 문제 해석으로 시작하겠습니다
적록색약을 가진 사람은 빨간색과 초록색을 같은 색으로 인식합니다.
주어진 image이미지는 N x N 형태로 이루어져 있습니다.
구역 을 구해야 하는데, 같은 색상이 상 하 좌 우 인접해 있는 경우 두 글자를 같은 구역에 속한다고 표현합니다.
이때 적록색약의 경우 빨간색과 초록색을 같은색으로 인식하기에 이에 대한 조건을 걸어주셔야 합니다.
이 문제의 경우 모든 image 구간을 탐색하면서 bfs보단 dfs로 탐색하는 것이 좋다고 생각해 dfs 탐색을 통해
특정한 구역을 모두 탐색할 경우 특정 색 "R, G , B" -> "V"(Visited)로 바꾸었습니다.
일반적인 사진 탐색은 그냥 dfs를 구현하면 되는데,
적록색약의 경우,
특정 좌표에 색이 "R" 이나 "G"일 때 탐색을 계속하도록 하는 조건을 걸어야해서 dfs함수를 총 2개 만들었습니다...(같은 코드가 몇갠지;;ㅠㅠㅠ)
구현을 성공적으로 하고, 다른 분들의 코드를 참고했고, 주어진 String에서 특정 char -> char로 바꾸는 메서드를 알게 되었습니다.
//일반적인 사람
func dfs(currentX x : Int, currentY y : Int, image : inout[[String]]){
var stack = [(Int,Int)]()
let char = image[y][x]
stack.append((x,y))
while(stack.count != 0){
let coord = stack.popLast()!
for (dx,dy) in direction{
let nx = dx + coord.0
let ny = dy + coord.1
if nx < 0 || nx > n - 1 || ny < 0 || ny > n - 1 {
continue
}
if image[ny][nx] == char {
stack.append((nx,ny))
image[ny][nx] = "V"
}
}
}
}
//적록색약
func _RG_dfs(currentX x: Int, currentY y : Int){
var stack = [(Int,Int)]()
let char = RGImage[y][x]
var rgWeakness = false
if char == "R" || char == "G" {
rgWeakness = true
}
stack.append((x,y))
while(stack.count != 0){
let coord = stack.popLast()!
for (dx,dy) in direction{
let nx = dx + coord.0
let ny = dy + coord.1
if nx < 0 || nx > n - 1 || ny < 0 || ny > n - 1 {
continue
}
if rgWeakness == true{
if RGImage[ny][nx] == "R" || RGImage[ny][nx] == "G"{
stack.append((nx,ny))
RGImage[ny][nx] = "V"
}
}else if RGImage[ny][nx] == char {
stack.append((nx,ny))
RGImage[ny][nx] = "V"
}
}
}
}
그래서 더 이상 _RG_dfs() 함수는 필요가 없어졌습니다.
적록색약 사람은 R == G 같은 색으로 보기에 두가지 글자중 한가지 글자로 변환하게 된다면 dfs()탐색만 하면 되기 때문입니다.
그래서 다음은
String.replacingOccurrences(of:with:) 메서드를 사용한 코드입니다.
import Foundation
var n = Int(readLine()!)!
var direction = [(-1,0),(1,0),(0,1),(0,-1)]
var image = Array(repeating: [String](), count: n)
/**
* imgae는 일반인의 시각에서 그룹의 방문을 탐색할 때 사용.
* RGImage는 적록색약
* 방문했을 경우 특정 좌표의 명암도가 "R,G,B" - > "V"
*/
var RGImage = image
var rImg = 0
var rRGImg = 0
/**
* String의 특정 char를 다른 특정 char로 변환하는 함수
* replacingOccurrences(of:with:)
* 이때 이 함수를 사용한 문자열은 그대로고, of:with: 조건이 반영된 문자열은 반환이 된다!
*/
for y in 0..<n{
var colors = readLine()!
image[y] = colors.map{String($0)}
colors = colors.replacingOccurrences(of: "G", with: "R")
RGImage[y] = colors.map{String($0)}
}
/**
* 이미지에서 모든 구간에 대해 탐색!
* 이때 dfs를 통해 방문했을 경우 "V"로 바꾸어 방문 완료 표시!
*/
for y in 0..<n{
for x in 0..<n{
if image[y][x] != "V"{
dfs(currentX: x, currentY: y, image: &image)
rImg += 1
}
if RGImage[y][x] != "V"{
dfs(currentX: x, currentY : y, image: &RGImage)
rRGImg += 1
}
}
}
print("\(rImg) \(rRGImg)")
/**
* 맨 처음 방문하지 않은 (x,y) 좌표의 문자를 char에 저장하고,
* char를 기준으로 탐색해야 할 이미지의 색이 char이라면 stack에 저장! -> 탐색의 반복!!
*/
func dfs(currentX x : Int, currentY y : Int, image : inout[[String]]){
var stack = [(Int,Int)]()
let char = image[y][x]
stack.append((x,y))
while(stack.count != 0){
let coord = stack.popLast()!
for (dx,dy) in direction{
let nx = dx + coord.0
let ny = dy + coord.1
if nx < 0 || nx > n - 1 || ny < 0 || ny > n - 1 {
continue
}
if image[ny][nx] == char {
stack.append((nx,ny))
image[ny][nx] = "V"
}
}
}
}
'백준 PS일지 > DFS&BFS' 카테고리의 다른 글
[백준/Swift] 2583 : 영역 구하기 (0) | 2022.05.12 |
---|---|
[백준/Swift] 2573 : 빙산 (0) | 2022.05.05 |
[백준/Swift] 7562 : 나이트의 이동 (0) | 2022.05.02 |
[백준/Swift] 2589번 : 보물섬 (0) | 2022.04.03 |