일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- boj 2206
- boj 1503
- 백준 1806
- 10800
- 2167
- boj 2635
- boj 2167
- boj 10800
- boj 2636
- 백준 19238
- boj 2108
- boj 2667
- boj 19238
- 백준 2178
- 백준 1697
- 백준 2661
- 백준 2108
- 백준 2206
- 백준 10800
- 백준 1503
- 2636
- 백준 2470
- 백준 2636
- boj 2661
- boj 1806
- 백준 2167
- boj 1697
- 백준 2635
- boj 2178
- boj 2470
- Today
- Total
말랑말랑한 개발자 이야기
[백준 15732번] 도토리 숨기기 본문
[백준 15732번] 도토리 숨기기
문제
HEPC 1등 상금으로 도토리 D개를 받은 욕심많은 다람쥐 수형이는 자신의 모든 도토리를 뺏기지 않게 보관하려고 한다. 수형이는 1부터 N까지의 번호가 붙여있는 N개의 상자를 가지고 있고 이 안에 도토리를 넣어 다른 다람쥐들이 찾지 못하게 전부 숨기려고 한다. 상자가 너무 많아 도토리가 있는 상자를 모두 외울 수 없는 수형이는 A번 상자부터 B번 상자까지 C개 간격으로 도토리를 하나씩 더 넣는 규칙을 만들었다! 다른 다람쥐들이 규칙을 눈치채고 모든 도토리를 잃는 것이 무서운 나머지 이러한 규칙들을 K개를 만들어 도토리를 최대한 안전하게 저장해 놓으려고 한다. 예를 들어 100번 상자부터 150번상자까지 10개 간격으로, 110번 상자부터 150번 상자까지 15개 간격으로 넣는다면 100, 110, 120, 125, 130, 140, 150번 상자에 도토리가 있으며 110번 상자와 140번 상자에는 2개의 도토리가 들어가 있게 된다. 상자 하나에 들어갈 수 있는 도토리의 개수는 제한이 없으며 앞의 상자부터 최대한 꽉꽉 채워나간다고 했을 때 마지막 도토리가 들어가 있는 상자의 번호를 출력하는 프로그램을 작성하시오.
입력
첫째 줄에 상자의 개수 N(1 ≤ N ≤ 1,000,000)과 규칙의 개수 K(1 ≤ K ≤ 10,000), 도토리의 개수 D(1 ≤ D ≤ 1,000,000,000)가 주어진다. 그 후 K개 줄에는 A, B, C(1 ≤ C ≤ A ≤ B ≤ N)가 주어지며 A번 상자부터 B번 상자까지 C개 간격으로 도토리를 하나씩 넣는 규칙을 뜻한다. D는 모든 규칙으로 넣을 수 있는 도토리의 수보다 같거나 작다.
출력
D개의 도토리를 규칙에 맞게 상자 앞에서부터 넣었을 때 마지막 도토리가 들어가는 상자의 번호를 출력하시오.
풀이
#include <iostream>
using namespace std;
int main() {
int N, K, D; cin >> N >> K >> D;
int arr[10000][3];
for(int i=0;i<K;i++){
for(int j=0;j<3;j++){
cin >> arr[i][j];
}
}
int pl = 0;
int pr = N;
int result;
while(pl <= pr){
long long cnt = 0;
int mid = (pl + pr) / 2;
for(int i=0;i<K;i++){
int k = min(mid, arr[i][1]);
if(k >= arr[i][0]){
cnt += (k - arr[i][0]) / arr[i][2] + 1;
}
}
// cout << pl <<' ' << pr <<','<< mid << ',' << cnt << '\n';
if(cnt >= D){
result = mid;
pr = mid - 1;
}
else pl = mid + 1;
}
cout << result;
return 0;
}
이분탐색으로 풀면 되는 문제라는 것은 빠르게 캐치를 했지만, 실제로 조건에 맞게 푸는데 애를 먹었다. 10번정도 틀렸습니다를 받으면서 이분탐색 문제에 대해 푸는 방법을 약간 정형화시키게 되었다. 일단 while문의 조건은 pl <= pr로 고정, 그리고 문제에서 요구하는 조건에 따라 pl이나 pr을 mid - 1이나 mid + 1로 옮겨주고, 실제 구하는 값은 result 변수로 따로 관리 하기, 마지막으로 수의 범위가 int의 범위를 벗어날 경우를 고려하여 long long 선언 등이 있다. 많이 틀렸음에도 불구하고 얻어가는 것이 많아서 좋은 문제였다고 생각한다.
'알고리즘 > 백준' 카테고리의 다른 글
[백준 10971번] 외판원 순회2 (0) | 2021.06.22 |
---|---|
[백준 18232번] 텔레포트 정거장 (0) | 2021.06.21 |
[백준 10775번] 공항 (0) | 2021.06.18 |
[백준 16562번] 친구비 (0) | 2021.06.18 |
[백준 20152번] Game Addiction (0) | 2021.06.18 |