무지개곰
article thumbnail
반응형

문제

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

입력

입력 첫 줄에는 테스트케이스의 개수 T가 주어진다. 그다음 줄부터 각각의 테스트케이스에 대해 첫째 줄에 출발점 (x1, y1)과 도착점 (x2, y2)이 주어진다. 두 번째 줄에는 행성계의 개수 n이 주어지며, 세 번째 줄부터 n 줄에 걸쳐 행성계의 중점과 반지름(c1, c2, r)이 주어진다.

2
-5 1 12 1
7
1 1 8
-3 -1 1
2 2 2
5 5 1
-4 5 1
12 1 1
12 1 2
-5 1 5 1
1
0 0 2

출력

각 테스트 케이스에 대해 어린 왕자가 거쳐야 할 최소의 행성계 진입/이탈 횟수를 출력한다.

3
0

문제 풀이

문제 해석 및 계획

도착지와 출발지를 감싸고 있는 원의 개수가 정답이라고 생각하였습니다. 그중에서 도착지와 출발지를 동시에 포함하고 있는 원은 개수를 새지 않아야 합니다.

원의 좌표와 반지름을 입력하면 특정 좌표를 포함하고 있는지 확인하는 함수를 만들고 bool값을 반환합니다.

도착지와 출발지를 각각 입력하여 출력이 다르면 answer를 1 증가하도록 하여 반복이 종료되면 출력하여야겠다고 생각하였습니다.

오답 노트

처음에 Fscan과 Fscanln을 함께 사용하였습니다.

testNum은 Fscan으로 x1, y1, x2, y2와 planetsNum을 Fscanln으로 입력을 받았습니다.

두 입력을 혼용하여 사용하니 x1, y1, x2, y2가 0 0 0 0으로 입력받아지는 문제가 발생하였습니다.

역시 Fscan과 Fscanln의 차이를 몰라서 발생한 문제였습니다.

알아보니 Fscan은 개행문자를 남겨두고 입력을 처리하고 Fscanln은 개행문자까지 읽어 입력을 처리한다고 합니다.

따라서 testNum이 Fscan으로 입력받아 개행문자를 남겼고 다음 Fscanln입력에서 남아있던 개행문자를 처리하여 0 0 0 0으로 입력되었습니다.

Fscan과 Fscanln을 혼용하지 않고 한 가지를 선택하여 해결하였습니다.

정답

package main

import (
	"bufio"
	"fmt"
	"os"
)

func main(){
	rx := bufio.NewReader(os.Stdin)
	wx := bufio.NewWriter(os.Stdout)
	
	defer wx.Flush()
	var testNum int

	fmt.Fscan(rx, &testNum)

	for i:=0 ; i<testNum ; i++ {
		var answer int = 0
		var x1, y1, x2, y2 int
		fmt.Fscan(rx, &x1, &y1, &x2, &y2)
		var planetsNum int
		fmt.Fscan(rx,&planetsNum)
		for j := 0 ; j<planetsNum ; j++ {
			var x, y, r int
			fmt.Fscan(rx, &x, &y, &r)
			if checkIn(x1, y1, x, y, r) != checkIn(x2, y2, x, y, r) {
				answer++
			}
		}
		fmt.Fprintln(wx, answer)
	}
}

func checkIn(cx1,cy1,x1,y1,r int) bool{
	return mathPow(x1-cx1) + mathPow(y1-cy1) < mathPow(r)
}

func mathPow(v int) int{
	return v*v
}

느낀 점

이전부터 로직보다 기초 문법이 어떻게 작동하는지를 확실히 알아두는 것이 프로그래밍을 하는데 가장 중요하다고 생각되었습니다.

쉬워 보이는 문제라도 이렇게 자세히 문법을 다루며 기초를 다질 수 있으니 최대한 모든 문제를 제대로 풀어보겠다는 다짐이 더욱 굳어졌습니다.

반응형
profile

무지개곰

@무지개곰

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!