danbibibi
article thumbnail
Published 2023. 12. 22. 08:14
BOJ 8983번: 사냥꾼 문제 풀이/백준

문제

문제 바로가기> BOJ 8983번: 사냥꾼

 

8983번: 사냥꾼

입력의 첫 줄에는 사대의 수 M (1 ≤ M ≤ 100,000), 동물의 수 N (1 ≤ N ≤ 100,000), 사정거리 L (1 ≤ L ≤ 1,000,000,000)이 빈칸을 사이에 두고 주어진다. 두 번째 줄에는 사대의 위치를 나타내는 M개의 x-좌

www.acmicpc.net

 

풀이

중요한 포인트는 "사대를 기준으로 동물을 보는 것"이 아니라, "동물을 기준으로 사대를 보는 것"이다.

사대를 정렬해두고, 해당 동물을 잡을 수 있는 사대가 있는지 이분탐색을 이용하여 확인하면,

 

MlogM(사대 정렬) + NlogN(나를 잡을 수 있는 사대 찾기)

O(MlogM) 만에 문제를 해결할 수 있다. 

#include<iostream>
#include<algorithm>
#define MAX 100001
using namespace std;

struct ANIMAL{int a, b;};

int M, N, L;
int gun[MAX];
ANIMAL animal[MAX];

void input(){
    cin >> M >> N >> L;
    for(int i=0; i<M; i++) cin >> gun[i];
    for(int i=0; i<N; i++) cin >> animal[i].a >> animal[i].b;
}

int upperBound(int x){ // x 이하 중 최대를 찾음 (사대)
    int upper = -1;
    int low=0, mid, high=M-1;
    while(low <= high){
        mid = (low+high)/2;
        if(gun[mid] <= x){
            upper = mid;
            low = mid+1;
        }
        else high = mid-1;
    }
    return upper;
}

void solve(){
    int ans = 0;

    // 1. 사대 정렬
    sort(gun, gun+M);

    // 2. 동물을 기준으로 사대를 본다.
    for(int i=0; i<N; i++){
        int low = animal[i].a + animal[i].b - L; // i번 동물을 잡을 수 있는 사대 (하한)
        int high = L + animal[i].a - animal[i].b;  // i번 동물을 잡을 수 있는 사대 (상한)
        int upper = upperBound(high);
        if(upper!=-1 && low<=gun[upper]) ans++;
    }
    cout << ans;
}

int main(){
    ios_base::sync_with_stdio(0); cin.tie(0);
    input();
    solve();
}

'문제 풀이 > 백준' 카테고리의 다른 글

BOJ 2666번: 벽장문의 이동  (0) 2024.01.03
BOJ 10157번: 자리배정  (0) 2023.12.27
BOJ 1079번: 쇠막대기  (0) 2023.12.15
BOJ 9047번: 6174  (0) 2023.12.11
BOJ 2304번: 창고 다각형  (0) 2023.09.05
profile

danbibibi

@danbibibi

꿈을 꾸는 시간은 멈춰 있는 것이 아냐 두려워하지 마 멈추지 마 푸른 꿈속으로