실버Ⅳ
https://www.acmicpc.net/problem/24313
시간 제한 | 메모리 제한 | 제출 | 정답 | 맞힌 사람 | 정답 비율 |
1 초 | 512 MB | 3684 | 1168 | 1021 | 31.464% |
문제
오늘도 서준이는 점근적 표기 수업 조교를 하고 있다. 아빠가 수업한 내용을 학생들이 잘 이해했는지 문제를 통해서 확인해보자.
알고리즘의 소요 시간을 나타내는 O-표기법(빅-오)을 다음과 같이 정의하자.
O(g(n)) = {f(n) | 모든 n ≥ n0에 대하여 f(n) ≤ c × g(n)인 양의 상수 c와 n0가 존재한다}
이 정의는 실제 O-표기법(https://en.wikipedia.org/wiki/Big_O_notation)과 다를 수 있다.
함수 f(n) = a1n + a0, 양의 정수 c, n0가 주어질 경우 O(n) 정의를 만족하는지 알아보자.
입력
첫째 줄에 함수 f(n)을 나타내는 정수 a1, a0가 주어진다. (0 ≤ |ai| ≤ 100)
다음 줄에 양의 정수 c가 주어진다. (1 ≤ c ≤ 100)
다음 줄에 양의 정수 n0가 주어진다. (1 ≤ n0 ≤ 100)
출력
f(n), c, n0가 O(n) 정의를 만족하면 1, 아니면 0을 출력한다.
예제 입력 1
7 7
8
1
예제 출력 1
0
f(n) = 7n + 7, g(n) = n, c = 8, n0 = 1이다. f(1) = 14, c × g(1) = 8이므로 O(n) 정의를 만족하지 못한다.
예제 입력 2
7 7
8
10
예제 출력 2
1
f(n) = 7n + 7, g(n) = n, c = 8, n0 = 10이다. 모든 n ≥ 10에 대하여 7n + 7 ≤ 8n 이므로 O(n) 정의를 만족한다.
풀이 방법
우선 이 문제는 입력값 a1, a0, c, n0를 입력받았을 때 n0보다 크거나 같은 n에 대하여 모든 n이
f(n) ≤ c × g(n)
*f(n) = a1 x n + a0
*g(n) = c x n
이 식을 만족하는지를 판단하는 문제입니다.
여기서 n은 무조건 n0보다 큰 값이므로 다음과 같이 식을 코드로 작성할 수 있습니다.
a1 * n0 + a0 <= c * n0
하지만 코드 내의 식을 단순히 이렇게만 작성한다면 91%에서 '틀렸습니다' 가 뜰 것입니다.
그 이유는 a0에 음의 정수 즉, 마이너스(-) 값이 들어간 경우가 있을 수 있기 때문입니다.
입력값이 a1 = 4, a0 = -3, c = 3, n0 = 1인 경우 즉,
4n - 3 ≤ 3n (n ≥ 1)
다음과 같이 식이 작성될 경우 n=1이라면 부등식의 좌항은 1, 우항은 3이 되기 때문에 O(n)의 정의를 만족하여 1을 출력하겠지만, 사실은 n=7일 때 좌항은 25, 우항은 21이 되기 때문에 O(n)의 정의를 만족하지 못하여 0을 출력해야 합니다.
그렇다면 입력값이 a1 = -1, a0 = 15, c = 8, n0 = 1인 경우처럼 a0이 음의 정수가 아닌, a1이 음의 정수가 되는 경우는 어떨까요?
-n+15 ≤ 8n (n ≥ 1)
이 경우 다음과 같인 부등식이 만들어 지고, n=1일 때 부등식의 좌항은 14, 우항은 8이 되어 O(n)의 정의를 만족하지 못하지만, n=5 일때 좌항은 10, 우항은 40으로 O(n)의 정의를 만족하게 됩니다.
하지만, 이 경우 처음부터 O(n)의 정의를 만족하지 못한다는 사실을 알게 되므로, 올바른 답이 출력됩니다.
즉, a1이 음의 정수 일때는 예외처리를 해주지 않아도 되지만, a0가 음의 정수 일때는 예외처리를 해주어야 한다는 사실을 알 수 있습니다.
따라서, 부등식 양변의 n의 차수(a1의 값과 c의 값)의 관계가 a0가 음수일 때 a1 ≤ c가 성립해야 함을 알 수 있습니다. 또한, a0가 양수일 때도 a1의 값이 c의 값보다 크다면 그 결과는 무조건 0이 되므로,
if (a1 * n0 + a0 <= c * n0 && a1 <= c)
이와 같이 코드를 작성할 수 있음을 알 수 있습니다.
내 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
#include <iostream>
using namespace std;
/*
C언어의 경우 cin은 scanf로, cout은 printf로 바꾸어 코드를 작성하면 된다.
*/
int main() {
int a1, a0;
cin >> a1 >> a0;
int c;
cin >> c;
int n0;
cin >> n0;
if (a1 * n0 + a0 <= c * n0 && a1 <= c)
cout << 1 << endl;
else
cout << 0 << endl;
return 0;
}
|
cs |
코드설명
a1, a0, c, n0를 차례로 입력받고,
a1 * n0 + a0 <= c * n0 && a1 <= c
이 조건을 만족하면 1, 만족하지 않으면 0을 출력하는 코드입니다.
'백준 알고리즘 단계별로 풀어보기 > 시간 복잡도' 카테고리의 다른 글
백준 알고리즘 24266번 알고리즘 수업 - 알고리즘의 수행 시간 5 (C++/C언어) (0) | 2023.03.24 |
---|---|
백준 알고리즘 24265번 알고리즘 수업 - 알고리즘의 수행 시간 4 (C++/C언어) (0) | 2023.03.22 |
백준 알고리즘 24264번 알고리즘 수업 - 알고리즘의 수행 시간 3 (C++/C언어) (0) | 2023.03.20 |
백준 알고리즘 24263번 알고리즘 수업 - 알고리즘의 수행 시간 2 (C++/C언어) (1) | 2023.03.19 |
백준 알고리즘 24262번 알고리즘 수업 - 알고리즘의 수행 시간 1 (C++/C언어) (0) | 2023.03.19 |