문제
흔한 수학 문제 중 하나는 주어진 점이 어느 사분면에 속하는지 알아내는 것이다. 사분면은 아래 그림처럼 1부터 4까지 번호를 갖는다. "Quadrant n"은 "제n사분면"이라는 뜻이다.
예를 들어, 좌표가 (12, 5)인 점 A는 x좌표와 y좌표가 모두 양수이므로 제1사분면에 속한다. 점 B는 x좌표가 음수이고 y좌표가 양수이므로 제2사분면에 속한다.
점의 좌표를 입력받아 그 점이 어느 사분면에 속하는지 알아내는 프로그램을 작성하시오. 단, x좌표와 y좌표는 모두 양수나 음수라고 가정한다.
입력
첫 줄에는 정수 x가 주어진다. (−1000 ≤ x ≤ 1000; x ≠ 0) 다음 줄에는 정수 y가 주어진다. (−1000 ≤ y ≤ 1000; y ≠ 0)
출력
점 (x, y)의 사분면 번호(1, 2, 3, 4 중 하나)를 출력한다.
예제 입력
10 10 |
예제 출력
1 |
풀이
최대한 짧게 짤 수 있는 방법을 생각하다가 x와 y의 범위에 따라 삼항연산자로 참일 때와 거짓일 때의 출력으로 나누기로 했다.
그런데 여기서 문제가 생겼다. 사분면의 수는 4개이고 참과 거짓의 판단은 2가지 뿐이었다. 하나의 변수에 조건에 따른 참일때의 값, 거짓일때의 값을 넣기에는 무리가 있었다.
가령 Quad라는 변수 하나로 삼항연산자를 만든다면
Quad = x>0 && y>0 ? 1 : 2 ;
Quad = x<0 && y>0 ? 2 : 3 ;
Quad = x<0 && y<0 ? 3 : 4 ;
Quad = x>0 && y<0 ? 4 : 1 ;
이런 식으로 될 것이다. 만약 제 1사분면의 좌표를 입력했다면 1이 무사히 출력될 것이다. 하지만 제 2사분면의 좌표를 입력한다면? 1이 출력된다. 그러므로 이 방법은 틀렸다. 혹시 몰라서 퀴즈가 아닌가? 하고 계속해서 생각해 봤지만 마지막 Quad에서 2가지의 출력만이 가능하므로 더 이상 생각해봤자 머리만 아파질 뿐이다.
그래서 생각한 방법은 삼항연산자에 쓸 변수를 2개로 만드는 것이었다. 처음 말했다시피 나는 최대한 짧게 만드는 것이 목적이었기에 2개로 한 것이다.
변수 Quad1or2와 Quad3or4를 선언하였다. 그 다음은 변수의 이름에서 알 수 있듯이 Quad1or2에는 제 1또는 2사분면을 판별할 것이고 Quad3or4에는 제 3또는 4사분면을 판별하여 집어넣을 것이다.
Quad1or2 = x>0 && y>0 ? 1 : 2 ;
Quad3or4 = x<0 && y<0 ? 3 : 4 ;
Quad1or2 에는 1또는 2가 들어갈 것이고, Quad3or4 에는 3또는 4가 들어갈 것이다. 이 다음에는 무엇을 해야할까? 판별이 완료 되었으니 출력을 해야한다.
여기서 또 문제가 발생한다. 출력이 될 때는 Quad1or2 와 Quad3or4 둘중에 하나만 출력이 되어야 하는데 어떻게 해야할까? 포인트는 두 변수의 차이점이다. 좌표평면을 보면 알 수 있듯이 제 1과 2사분면은 y>0 이 되고, 제 3과 4사분면은 y<0이 된다. 그래서 두 변수를 한 번 더 판별하기 위해서 y의 범위를 사용한다. 그럼 Quad1or2 와 Quad3or4 을 설정할 때 x에 대한 범위만 넣어도 되는거 아닌가? 라고도 생각을 확장 할 수 있게 된다. 그리고 출력에 사용할 변수 Quad 를 하나 더 선언해 준다.
Quad = y > 0 ? (Quad1or2 = ( x > 0 ) ? 1 : 2) : (Quad3or4 = ( x < 0 ) ? 3 : 4);
이렇게 된다면 이제 x와 y의 마지막 조건인 −1000 ≤ x ≤ 1000; x ≠ 0 과 −1000 ≤ y ≤ 1000; y ≠ 0 만이 남게 된다. x와 y가 0이 되는 조건은 이미 0을 포함하지 않으므로 만족하지만, 최대값과 최솟값을 구하면 끝이 난다.
만약 삼항연산자의 조건 란에 x의 범위를 -1000<=x<=1000 으로 쓴다면, 엉뚱한 값이 나올 것이다. -1000<=x<=1000 은 c언어에서는 쓰지 못하므로 &으로 따로따로 써줘야 한다는 점을 주의하자.
Quad = y>0? (Quad1or2 = (x > 0 && x <= 1000 && y <= 1000) ? 1 : 2):
(Quad3or4 = (x<0 && x >= -1000 && y >= -1000) ? 3 : 4);
이렇게 해서 출력할 변수에 어떤식으로 수를 넣을지는 결정이 되었다.
#include <stdio.h>
int main(void)
{
int x, y, Quad1or2, Quad3or4, Quad;
scanf_s("%d\n%d", &x, &y);
Quad = y>0? (Quad1or2 = (x > 0 && x <= 1000 && y <= 1000) ? 1 : 2):
(Quad3or4 = (x<0 && x >= -1000 && y >= -1000) ? 3 : 4);
printf("%d\n", Quad);
}
완성.
후기
세탁기를 기다리며 겸사 겸사 짠 코드인데, 문제는 그 시간대가 12시 였다. 평소같으면 11시에 잠 자리에 들었지만 건조기도 돌려야 한다는 생각에 스트레스 받으며 눈을 말똥소똥 뜨며 기다렸다. 세탁기가 끝나갈 때 쯤에 건조기를 돌리러 갔는데 두개 있는 건조기에 3개의 세탁기가 돌아가고 있었다. 마침 나의 세탁기가 제일 느리게 가서 20분 가량을 그 앞에서 서 있었다. 사실 처음에 넣을 때에 깨달아서 이미 늦었다고 생각했을 때에는 카드 찍고 세제를 넣을 때였다. 서 있는데 그 순간 누군가가 와서 하나의 세탁기에서 세탁물을 꺼냈다. 하.. 아찔 했다. 하나 남은 건조기가 있고 아직 나머지 한 명은 안 왔으니 난 괜찮을 거다.. 이 생각을 하고 있었다. 내 앞 사람이 세탁물을 건조기에 하나 둘 넣을 때까지도 나머지 한 세탁기는 끝났는데도 주인이 안 왔다. 정말 다행이었고 안도의 숨을 내뱉었다. 그런데 방심은 금물이다. . . 앞 사람이 건조기에 모두 다 넣자 갑자기 끝난 세탁기의 문을 열었다. 아뿔사. 당신이 그 세탁기의 주인이었군요. . . 건조기는 하나야 둘이 될 수없지만.. 그래도... 다리를 ><해서 풀썩 주저앉고 싶은 심정이었다. 그래도 혹시 몰라서 계속 지켜봤다. 그 사람은 이어폰을 끼고 있어서 아무 말도 하지 못했다. 저기.. 저 정말 자고 싶어요.. 3시에 못 자요.. 이렇게 말하고 싶었지만 그 사람은 이어폰을 끼고 있었다. 크게 좌절하며 해탈하고 있는 순간, 그 분이 그 세탁물을 들고 그냥 나가버리셨다. 내가 빤히 쳐다봐서 봐준다 해서 나가신건지 아니면 건조대가 있어서 나가신 건지는 못 물어봤지만, 아무튼 새벽에 이렇게 쫄깃한 적은 오랜만인 것 같다. 감동 실화다. 잠이 깨서 4시에 잤다.
'코딩테스트' 카테고리의 다른 글
[Python] 백준 4344 풀이 (0) | 2022.12.30 |
---|---|
[Python, C] 백준 1110번 풀이 (0) | 2022.12.29 |
[Python] 백준 1546 풀이 (0) | 2022.12.29 |
[C언어] 백준 5554 풀이 (0) | 2022.05.06 |
[C언어] 백준 3046 풀이 (0) | 2022.05.05 |