#include <iostream>

using namespace std;

typedef long long ll;

int n,m;
int tb1[100001];
int main(void)
{
    cin >> n >> m;
    for(int i=0;i<m;++i){
        cin >> tb1[i];
    }
    if(n<=m){
        cout << n << endl;
        return 0;
    }
    ll left = 0;
    ll right = 2000000000LL * 1000000LL ;
    ll mid;
    while(left <= right){
        mid = (left + right) / 2;
        //cout << mid << endl;

        ll st_cnt = 0;
        ll st_cnt_min = 0;
        st_cnt = m;
        for(int i=0;i<m;++i){
            st_cnt += mid / tb1[i];
        }
        st_cnt_min = st_cnt;
        for(int i=0;i<m;++i){
            if(mid % tb1[i] == 0){
                st_cnt_min--;
            }
        }    
        
        st_cnt_min++;
        if(n > st_cnt){
            left = mid + 1;
            
        }
        else if(n < st_cnt_min){
            right = mid - 1;
        }
        else{
            for(int i=0;i<m;++i){
                if(mid % tb1[i] == 0){
                    if(n == st_cnt_min){
                        cout << i+1;
                        return 0;
                    }
                    st_cnt_min++;
                }
            }
        }
    }
    return 0;
}


'알고리즘' 카테고리의 다른 글

[BS] 백준 2512 예산  (0) 2018.04.29
[BS] 백준 1939 중량제한  (0) 2018.04.29
[BS] 백준 3020 개똥벌레  (0) 2018.04.29
[BS] 백준 1300 k번째 수  (0) 2018.04.29
[BS] 백준 3079 입국심사  (0) 2018.04.29

  • 풀고나면 쉽지만 풀기까지 힘든 문제.
  • n을 0~n/2-1로 하지말고 1 ~ n/2 로 하는 방법도 있다. 

개똥벌레 성공


시간 제한
메모리 제한
제출
정답
맞은 사람
정답 비율
1 초
128 MB
2775
981
718
38.151%

문제
개똥벌레 한 마리가 장애물(석순과 종유석)로 가득찬 동굴에 들어갔다. 동굴의 길이는 N미터이고, 높이는 H미터이다. (N은 짝수) 첫 번째 장애물은 항상 석순이고, 그 다음에는 종유석과 석순이 번갈아가면서 등장한다.
아래 그림은 길이가 14미터이고 높이가 5미터인 동굴이다. (예제 그림)
이 개똥벌레는 장애물을 피하지 않는다. 자신이 지나갈 구간을 정한 다음 일직선으로 지나가면서 만나는 모든 장애물을 파괴한다.
위의 그림에서 4번째 구간으로 개똥벌레가 날아간다면 파괴해야하는 장애물의 수는 총 여덟개이다. (4번째 구간은 길이가 3인 석순과 길이가 4인 석순의 중간지점을 말한다)
하지만, 첫 번째 구간이나 다섯 번째 구간으로 날아간다면 개똥벌레는 장애물 일곱개만 파괴하면 된다.
동굴의 크기와 높이, 모든 장애물의 크기가 주어진다. 이 때, 개똥벌레가 파괴해야하는 장애물의 최소값과 그러한 구간이 총 몇 개 있는지 구하는 프로그램을 작성하시오.
입력
첫째 줄에 N과 H가 주어진다. N은 항상 짝수이다. (2 ≤ N ≤ 200,000, 2 ≤ H ≤ 500,000)
다음 N개 줄에는 장애물의 크기가 순서대로 주어진다. 장애물의 크기는 H보다 작은 양수이다.
출력
첫째 줄에 개똥벌레가 파괴해야 하는 장애물의 최소값과 그러한 구간의 수를 공백으로 구분하여 출력한다.
예제 입력 1 
14 5
1
3
4
2
2
4
3
4
3
3
3
2
3
3
예제 출력 1 
7 2



















































































#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int err = -99999999;
int up[100001]; // 종유석
int dn[100001]; // 석순
int n, h;
int upc(int tph) { // temp h
       int left = 0;
       int right = n / 2 - 1;
       while (left <= right) {
              int mid = (left + right) / 2;
              if (up[mid] >= tph) {
                     right = mid - 1;
              }
              else {
                     left = mid + 1;
              }
       }
       return n / 2 - left;
}
int dnc(int tph) {
       int left = 0;
       int right = n / 2 - 1;
       while (left <= right) {
              int mid = (left + right) / 2;
              if (dn[mid] >= tph) {
                     right = mid - 1;
              }
              else {
                     left = mid + 1;
              }
       }
       return n / 2 - left;
}
int main(void)
{
       cin >> n >> h;
       for (int i = 0; i<n / 2; ++i) {
              cin >> up[i];
              cin >> dn[i];
       }
       sort(up, up + n / 2);
       sort(dn, dn + n / 2);
       int minval = 999999;
       int mincnt = 1;
       for (int i = 1; i <= h; ++i) {
              int temp = upc(i) + dnc(h - i + 1);
              if (temp == minval) {
                     mincnt++;
              }
              else if (temp < minval) {
                     mincnt = 1;
                     minval = temp;
              }
       }
       cout << minval << ' ' << mincnt << endl;
       return 0;
}






'알고리즘' 카테고리의 다른 글

[BS] 백준 1939 중량제한  (0) 2018.04.29
[BS] 백준 1561 놀이공원  (0) 2018.04.29
[BS] 백준 1300 k번째 수  (0) 2018.04.29
[BS] 백준 3079 입국심사  (0) 2018.04.29
[BS] 백준 2792 보석 상자  (0) 2018.04.29

  • n 제한도 잘 생각해야하고 잘 생각하자
  • 다시한번 상기시키지만 left 조건에 = 없이 써야한다. 3079 문제 참고


K번째 수 성공


시간 제한
메모리 제한
제출
정답
맞은 사람
정답 비율
2 초
128 MB
2302
705
522
35.104%

문제
세준이는 N*N크기의 배열을 만들었다. (배열의 방 번호는 1부터 시작한다.)
그 배열을 A라고 했을 때, 배열에 들어가는 수는 A[i][j] = i*j 이다.
세준이는 이 수를 일차원 배열 B에 넣으려고 한다. 그렇게 되면, B의 크기는 N*N이 될 것이다. 그러고 난 후에, B를 정렬해서 k번째 원소를 구하려고 한다.
N이 주어졌을 때, k번째 원소를 구하는 프로그램을 작성하시오.
입력
첫째 줄에 배열의 크기 N이 주어진다. N은 105보다 작거나 같은 자연수이다. 둘째 줄에 k가 주어진다. k는 min(109, n2)보다 작거나 같은 자연수이다.
출력
k번째 원소를 출력한다.
예제 입력 1 
3
7
예제 출력 1 
6










































#include <iostream>
#include <limits.h>
#include <algorithm>
using namespace std;
typedef long long ll;
const ll Imax = 1000000000000000000ll;
int main(void)
{
       ll n, k;
       cin >> n >> k;
       ll left = 0;
       ll right = min(n*n, 1000000000ll);
       while (left <= right) {
              ll mid = (left + right) / 2;
              ll cnt = 0;
              for (int i = 1; i <= n; ++i) {
                     cnt += min(mid / i, n);
              }
              if (cnt < k) {
                     left = mid + 1;
              }
              else {
                     right = mid - 1;
              }
       }
       cout << left << endl;
       return 0;
}


'알고리즘' 카테고리의 다른 글

[BS] 백준 1561 놀이공원  (0) 2018.04.29
[BS] 백준 3020 개똥벌레  (0) 2018.04.29
[BS] 백준 3079 입국심사  (0) 2018.04.29
[BS] 백준 2792 보석 상자  (0) 2018.04.29
[BS] 백준 1477 휴게소 세우기  (0) 2018.04.29

+ Recent posts