문제
https://www.acmicpc.net/problem/1063
입력
첫째 줄에 킹의 위치, 돌의 위치, 움직이는 횟수 N이 주어진다. 둘째 줄부터 N개의 줄에는 킹이 어떻게 움직여야 하는지 주어진다. N은 50보다 작거나 같은 자연수이고, 움직이는 정보는 위에 쓰여 있는 8가지 중 하나이다.
출력
첫째 줄에 킹의 마지막 위치, 둘째 줄에 돌의 마지막 위치를 출력한다.
문제 풀이
문제 해석 및 계획
움직이는 방향으로 이동이 가능한지 확인하고 이동하였을 경우 킹과 돌이 겹치게 된다면 돌이 움직일 수 있는지 확인하여 가능한 경우만 킹과 돌이 움직이고 겹치지 않는다면 킹만 움직이도록 생각하였습니다.
오답 노트
switch의 case를 몇 번이고 확인하였고 생각나는 테스트 케이스에 대하여 모두 통과하였지만 반복되는 오답으로 인하여 코드를 전체 수정하였습니다.
package main
import (
"bufio"
"fmt"
"os"
)
func main(){
reader := bufio.NewReader(os.Stdin)
writer := bufio.NewWriter(os.Stdout)
defer writer.Flush()
var (
King, Rock string
N int
)
fmt.Fscan(reader, &King, &Rock, &N)
K := make(map[string]byte)
K["x"] = King[0]
K["y"] = King[1]
R := make(map[string]byte)
R["x"] = Rock[0]
R["y"] = Rock[1]
for i:=0 ; i<N ; i++{
var command string
fmt.Fscan(reader, &command)
move(K, R, command)
}
fmt.Fprintf(writer, "%s%s\n",string(K["x"]), string(K["y"]))
fmt.Fprintf(writer, "%s%s\n",string(R["x"]), string(R["y"]))
}
func move(K, R map[string]byte, command string){
x, y:="x", "y"
switch command {
case "R" :
if K[x]+1 <= 'H'{
if K[x]+1==R[x] && K[y] == R[y] {
if R[x]+1 <= 'H' {
K[x]++
R[x]++
}
}else{
K[x]++
}
}
case "L" :
if 'A' <= K[x]-1 {
if K[x]-1 == R[x] && K[y] == R[y]{
if 'A' <= R[x]-1{
K[x]--
R[x]--
}
}else{
K[x]--
}
}
case "B" :
if '1' <= K[y]-1 {
if K[x] == R[x] && K[y]-1 == R[y]{
if '1' <= R[y]-1{
K[y]--
R[x]--
}
}else{
K[y]--
}
}
case "T" :
if K[y]+1 <= '8'{
if K[x] == R[x] && K[y]+1 == R[y] {
if R[y]+1 <= '8'{
K[y]++
R[y]++
}
}else {
K[y]++
}
}
case "RT" :
if K[x]+1 <= 'H' && K[y]+1 <= '8'{
if K[x]+1 == R[x] && K[y]+1 == R[y]{
if R[x]+1 <= 'H' && R[y]+1 <= '8'{
K[x]++
K[y]++
R[x]++
R[y]++
}
}else {
K[x]++
K[y]++
}
}
case "LT" :
if 'A' <= K[x]-1 && K[y]+1 <= '8' {
if K[x]-1 == R[x] && K[y]+1 == R[y] {
if 'A' <= R[x]-1 && R[y]+1 <= '8'{
K[x]--
K[y]++
R[x]--
K[y]++
}
}else{
K[x]--
K[y]++
}
}
case "RB" :
if K[x]+1 <= 'H' && '1' <= K[y]-1{
if K[x]+1 == R[x] && K[y]-1 == R[y]{
if R[x]+1 <= 'H' && '1' <= R[y]-1{
K[x]++
K[y]--
R[x]++
R[y]--
}
}else {
K[x]++
K[y]--
}
}
case "LB" :
if 'A' <= K[x]-1 && '1' <= K[y]-1 {
if K[x]-1 == R[x] && K[y]-1 == R[y]{
if 'A' <= R[x]-1 && '1' <= R[y]-1{
K[x]--
K[y]--
R[x]--
R[y]--
}
}else{
K[x]--
K[y]--
}
}
}
}
정답
위의 오답에서 예시로 주는 테스트 케이스와 질문에 존재하는 테스트 케이스를 모두 통과하였지만 반복되는 오류를 못 찾았습니다.
정답과의 차이는 오답의 경우는 움직이는 방향의 마지노선만 확인하였고 정답의 경우는 함수를 통하여 움직이는 방향의 마지노선뿐만 아니라 모든 방향의 마지노선을 확인한다는 차이라고 생각됩니다. 정확히 오답의 원인은 찾지 못하여 아쉬움이 남지만 함수의 장점인 코드의 재사용성을 높인 아래의 정답처럼 코드를 작성하는 것이 맞다고 생각됩니다.
package main
import (
"bufio"
"fmt"
"os"
)
func main(){
reader := bufio.NewReader(os.Stdin)
writer := bufio.NewWriter(os.Stdout)
defer writer.Flush()
var (
King, Rock string
N int
)
K := make(map[string]int)
R := make(map[string]int)
fmt.Fscan(reader, &King, &Rock, &N)
K["x"] = int(King[0]-'A')
K["y"] = int(King[1]-'1')
R["x"] = int(Rock[0]-'A')
R["y"] = int(Rock[1]-'1')
for i:=0 ; i<N ; i++{
var command string
fmt.Fscan(reader, &command)
switch command {
case "R" :
move(K, R, 1, 0)
case "L" :
move(K, R, -1, 0)
case "B" :
move(K, R, 0, -1)
case "T" :
move(K, R, 0, 1)
case "RT" :
move(K, R, 1, 1)
case "LT" :
move(K, R, -1, 1)
case "RB" :
move(K, R, 1, -1)
case "LB" :
move(K, R, -1, -1)
}
}
fmt.Fprintf(writer, "%s%s\n",string(byte(int('A')+K["x"])), string(byte(int('1')+K["y"])))
fmt.Fprintf(writer, "%s%s\n",string(byte(int('A')+R["x"])), string(byte(int('1')+R["y"])))
}
func move(K, R map[string]int, mx, my int){
x, y := "x", "y"
if 0 <= K[x]+mx && K[x]+mx <= 7 && 0 <= K[y]+my && K[y]+my <= 7{
if K[x]+mx == R[x] && K[y]+my == R[y]{
if 0 <= R[x]+mx && R[x]+mx <= 7 && 0 <= R[y]+my && R[y]+my <= 7 {
K[x]+=mx
K[y]+=my
R[x]+=mx
R[y]+=my
}
}else {
K[x]+=mx
K[y]+=my
}
}
}
느낀 점
반복되는 코드는 함수화 하여 줄여 사용하는 것이 수정도 편하고 오류를 검사하기도 편리하다고 느꼈습니다.
처음에는 move 함수를 만들었지만 조금 더 현명하게 사용하지 못하여 오류를 발견하기 어려웠지만 정답의 경우는 command의 모든 경우를 보지 않고 move 함수만 이해하고 매개변수만 확인한다면 전체 흐름을 이해할 수 있기에 통과할 수 있었습니다.
앞으로도 조금 더 생각하여 코드의 재사용성을 높이도록 하겠습니다.
'알고리즘 > 백준' 카테고리의 다른 글
[Go] 백준 1141번 접두사 (HasPrefix) (0) | 2023.09.12 |
---|---|
[Go] 백준 1124번 언더 프라임 (소수가 약점인 것 같습니다.) (0) | 2023.09.11 |
[Go] 백준 1052번 물병 (0) | 2023.09.09 |
[Go] 백준 24511번 queuestack (queue) (0) | 2023.09.08 |
[Go] 1152번 단어의 개수 (TrimSpace, Split) (0) | 2023.09.04 |