본문 바로가기

알고리즘 관련/BOJ

BOJ)15745 Snow Boots

문제: icpc.me/15745


1~N 영역에 쌓인 눈의 높이가 주어진다.


이제 B개의 신발에 대한 쿼리가 들어오는데 각 쿼리는 Si와 Di를 가진다. 


Si는 해당 신발을 신고 걸을 수 있는 최대 눈의 높이이고, Di는 한번에 최대로 걸을 수 있는 거리이다.


i번 째 신발을 신었을 때 1에서 부터 N까지 갈 수 있는 지 여부를 매 쿼리마다 출력해주면 되는 문제이다.


풀이법은 여러가지가 있는것 같지만 내가 푼 풀이는 오프라인 쿼리 풀이이다.


우선 쿼리를 Si기준으로 역순으로 정렬을 해준 뒤 순서대로 봐준다.


쿼리를 역순으로 본다면, 쿼리를 보면서 점점 못넘는 영역이 늘어날 것이다. 


현재 쿼리를 처리할 때 넘을 수 있는 기준은 현재 못넘는 영역중에서 가장 긴 영역이 되므로


역순으로 쿼리를 처리하면서, 못넘는 영역을 계속 처리해주면 된다. 못넘는 영역의 크기는 union find를 이용하면 쉽게 처리해줄 수 있다.


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
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <cstdio>
#include <algorithm>
#include <map>
#include <vector>
using namespace std;
int n,b,a[100010],m[100010],par[100010],sz[100010],r[100010],currmaxsize,finish;
map<int,vector<int>> mp;
vector<pair<pair<int,int>,int>> qry;
int find(int h){
    return h==par[h]?h:par[h]=find(par[h]);
}
void merge(int x,int y){
    x=find(x),y=find(y);
    if(x==y)return;
    par[x]=y;
    sz[y]+=sz[x];
}
int main(){
    scanf("%d%d",&n,&b);
    for(int i=1;i<=n;i++)par[i]=i,sz[i]=1;
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        mp[a[i]].push_back(i);
    }
    for(int i=0;i<b;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        qry.push_back({{x,y},i});
    }
    sort(qry.rbegin(),qry.rend());
    auto it=mp.end();
    it--;
    currmaxsize=0;
    for(int i=0;i<b;i++){
        while(!finish){
            if(it->first<=qry[i].first.first)break;
            for(auto idx:it->second){
                if(idx!=1&&m[idx-1])
                    merge(idx-1,idx);
                if(idx!=n&&m[idx+1])
                    merge(idx+1,idx);
                m[idx]=1;
                currmaxsize=max(currmaxsize,sz[find(idx)]);
            }
            if(it==mp.begin())finish=1;
            it--;
        }
        if(qry[i].first.second>currmaxsize)
            r[qry[i].second]=1;
    }
    for(int i=0;i<b;i++)printf("%d\n",r[i]);
    return 0;
}
cs


'알고리즘 관련 > BOJ' 카테고리의 다른 글

BOJ)14288 내리 갈굼4  (1) 2018.07.07
BOJ)14400 편의점2  (0) 2018.07.05
BOJ)13274 수열  (0) 2018.07.02
BOJ)15589 Lifeguards (Silver)  (0) 2018.06.26
BOJ)14965 Lozinke  (0) 2018.06.26