본문 바로가기

알고리즘/백준

백준 1654 랜선자르기(이분탐색)-C++

728x90

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

오늘부터 이분탐색 문제를 풀기 시작했다.

이분탐색 알고리즘은 간단하다. 찾고자 하는 값을 정렬시킨다음에(여기서는 자르려는 길이이므로 정렬할 필요가 없음)

  • 제일 큰값 제일 작은값의 중간을 탐색.
  • 그것보다 크냐 작냐를 가지고
  • 최댓값 또는 최솟값을 중간+-1을 시킨후
  • 1~3 반복해서 더이상 진행이 안될때까지 반복.

문제의 조건에 따라 ispossible (len의 길이로 자를 때 N또는 그 이상의 len짜리 조각이 나오느냐를 리턴) 함수를 만들었다.

중간에 한번 안된 적이 있는데, 이분탐색을 진행할때 mid의 값에 +-1을 해줘야 다음 값으로 넘어가면서 진행이 가능하다. 안할시 자칫하다간 무한루프에 빠져버린다..

 

 

코드

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
#include <iostream>
using namespace std;
long long lan[10001];
int K,N;
 
bool ispossible(long long len){
    int count=0;
    for(int i=0; i<K;i++){
        count+=lan[i]/len;
    }
    if (count>=N)
        return true;
    else
        return false;
}
 
int main(void){
    cin>>K>>N;
    long long high=0;
    for(int i=0; i<K; i++) {
        cin >> lan[i];
        high=max(high,lan[i]);
    }
    long long result=0;
    long long low=1;
    while(low<=high){
        long long mid = (low+high)/2;
        if(ispossible(mid)){
            if(result<mid)
                result=mid;
            low=mid+1;
        }
        else{
            high=mid-1;
        }
    }
    cout<<result;
 
}
 
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter