본문 바로가기

백준

백준1654 - 랜선 자르기

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

 

1654번: 랜선 자르기

첫째 줄에는 오영식이 이미 가지고 있는 랜선의 개수 K, 그리고 필요한 랜선의 개수 N이 입력된다. K는 1이상 10,000이하의 정수이고, N은 1이상 1,000,000이하의 정수이다. 그리고 항상 K ≦ N 이다. 그 후 K줄에 걸쳐 이미 가지고 있는 각 랜선의 길이가 센티미터 단위의 정수로 입력된다. 랜선의 길이는 231-1보다 작거나 같은 자연수이다.

www.acmicpc.net

이분탐색을 활용한 문제다. 현재 만들 수 있는 랜선의 갯수가 주어진 랜선의 갯수 이상이면 답을 갱신한다. 답을 찾으면 범위를 반으로 줄여 큰 쪽으로 탐색하기 때문에 현재 길이와 비교 과정이 없어도 가장 최근의 찾은 길이가 답이 된다. 

#include <iostream>
#include <vector>
using namespace std;

int main() {
	vector<int> v; //랜선의 길이
	int K, N;
	int num;
	int big = 0; //최댓값 찾는 변수
	unsigned long long int ans = 0; //만들 수 있는 최대 길이

	cin >> K >> N;
	for (int i = 0; i < K; i++) {
		cin >> num;
		v.push_back(num);
		if (big < num) {
			big = num;
		}
	}

	//처음 값과 끝 값 설정
	unsigned long long int left = 1;
	unsigned long long int right = big;

	//길이 탐색
	while (left <= right) {
		unsigned long long int mid = (left + right) / 2ull; //현재 길이 설정
		unsigned long long int cnt = 0; //자를 수 있는 랜선의 갯수

		//현재 만들 수 있는 총 랜선의 수
		for (int i = 0; i < v.size(); i++) {
			cnt = cnt + v[i] / mid;
		}

		if (cnt >= N) { //현재 만들 수 있는 총 랜선의 수가 N 이상이면
			ans = mid; //현재 길이로 갱신
			left = mid + 1; //범위를 큰 쪽으로 줄임
		}
		else { //현재 만들 수 있는 총 랜선의 수가 N보다 작으면
			right = mid - 1; //범위를 작은 쪽으로 줄임
		}
	}

	cout << ans;
}

'백준' 카테고리의 다른 글

백준2210 - 숫자판 점프  (0) 2020.01.19
백준2096 - 내려가기  (0) 2020.01.18
백준9372 - 상근이의 여행  (0) 2020.01.09
백준9019 - DSLR  (0) 2020.01.05
백준1669 - 멍멍이 쓰다듬기  (0) 2019.12.29