문제 : https://www.acmicpc.net/problem/2541
2541번: 점
첫째 줄에는 처음에 S에 속하는 점 (a, b)의 좌표인 두 자연수 a와 b가 하나의 공백을 두고 순서대로 주어진다. 그리고 그 다음 다섯 줄에는 각 줄마다 한 개의 점 (p, q)의 두 자연수 p와 q가 하나의
www.acmicpc.net
문제 파악하기
시작점 (a, b)에서 3가지 규칙을 사용하여 집합 S에 점을 추가할 때, 주어진 (x, y)가 집합 S에 포함될 수 있는지 여부를 확인하는 문제입니다. 입력되는 점의 범위는 1 ~ 100,000이기 때문에 단순히 모든 경우의 수를 파악할 수는 없습니다. 대신 규칙을 계속 적용할 때 나타나는 특징을 살펴보면 문제를 해결할 수 있습니다.
문제 해결하기
규칙 3가지를 적절하게 이용하면 우리는 항상 점 (a, b)의 a 와 b 중 하나 이상의 좌표값이 1인 점을 추가할 수 있습니다. 이는 (a, b)가 모두 짝수라면 규칙 3을 사용해서 나누어주고, 만약 나눌 수 없다면 규칙 1과 규칙 2를 사용해 짝수로 만들어주어 계속 나누는 알고리즘을 사용하면 됩니다. 예를 들어, 점 (5, 8)이 있다고 가정해보면 다음과 같은 과정을 통해 점 (1, 4)을 추가할 수 있습니다.
(5, 8) > (6, 9) > (6, 9) +(9, 12) = (6, 12) > (3, 6) > (4, 7) + (7, 10) = (4, 10) > (2, 5) > (2, 5) + (5, 8) = (2, 8) > (1, 4)
이렇게 모든 좌표를 항상 짝수로 만들어주면서 2로 계속 나누어주면 (a, b)의 a와 b 중 하나 이상의 좌표값이 1인 상태가 되며, 이 점이 우리가 추가할 수 있는 가장 작은 점의 좌표라고 할 수 있습니다.
이렇게 (a, b)를 사용하여 집합 S에 추가할 수 있는 가장 작은 점의 좌표를 구했다면 남은 일은 (x, y)를 추가할 수 있는지 여부를 파악하는 것입니다. 가능 여부를 확인할 때에 중점으로 확인할 값은 a와 b의 차이값(d)과 x와 y의 차이값(dd)입니다. 집합 S에 추가할 수 있는지 여부는 dd가 d의 배수인지에 여부에 따라 달라지게 됩니다. 만약 dd가 d의 배수라면, 즉 x와 y의 차이값(dd)이 a와 b의 차이값(d)의 배수라면 항상 (x, y)를 만들 수 있습니다. 이는 규칙 2번을 활용하면 쉽게 확인할 수 있습니다. 규칙 2번을 사용하면 a와 b의 차이값인 d가 배수만큼 증가하기 때문입니다. 그렇기에 반대로 dd가 d의 배수가 아니라면 (x, y)는 절대 만들 수 없습니다. 이렇게 d와 dd의 값을 통해 5개의 점을 확인하면 문제를 해결할 수 있습니다. 자세한 소스코드는 다음과 같습니다.
소스코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
#include <stdio.h>
int a, b, x, y;
int d, dd;
int abs(int k) { return k>=0 ? k:-k; }
int main() {
scanf("%d %d", &a, &b);
d = abs(b-a);
// (a, b)가 될 수 있는 가장 작은 숫자로 변환
if(a == b) a = b = 1;
else {
while(d%2 == 0) d /= 2;
if(a < b) {
a = 1;
b = 1+d;
}
else {
a = 1+d;
b = 1;
}
}
for(int i=1;i<=5;i++) {
scanf("%d %d", &x, &y);
if((a<=b) != (x<=y)) printf("N\n");
else {
dd = abs(y-x);
if(d*dd == 0) {
if(d == dd) printf("Y\n");
else printf("N\n");
}
else {
// dd%d == 0 이라면 숫자들을 조합해서 (x,y)를 만들 수 있음
if(dd%d == 0) printf("Y\n");
else printf("N\n");
}
}
}
}
|
cs |
후기
정올 1번에 어울리는 문제라고 생각합니다. 규칙들을 분석한 다음, 특징을 통해 복잡한 계산 없이 간단한 조건문으로 풀 수 있기에 정올을 처음 준비하는 사람들에게 소개할만한 문제라고 생각합니다.
'문제 노트 > 정올' 카테고리의 다른 글
주유소( BOJ 28219 ) (0) | 2023.08.20 |
---|---|
레벨 업( BOJ 25405 ) (0) | 2023.06.25 |
트리와 쿼리( BOJ 25402 ) (1) | 2022.09.30 |
커다란 도시( BOJ 25380 ) (1) | 2022.09.26 |
카드 바꾸기( BOJ 25401 ) (1) | 2022.09.22 |