백준 1981 배열에서의 이동

문제

풀이

이분탐색 + BFS

#include <iostream>
#include <cstring>
#include <queue>
using namespace std;

int board[100][100], n;


int dx[]={1, -1, 0, 0}, dy[]={0,0,-1,1};

bool isRange(int x, int y) {
    return x>=0 && x<n && y>=0 && y<n;
}

// 잘못짰다고... ㅠ _ ㅠ
bool canGo(int x, int y, int k) {
    for(int low=0; low<=200; ++low) {
        if(board[x][y]<low || board[x][y]>low+k)
            continue;
        bool visited[100][100] = {false,};
        queue<pair<int, int>> q;
        visited[x][y] = true;
        q.push({x, y});
        while (!q.empty()) {
            pair<int, int> here = q.front();
            q.pop();
            if (here.first == n - 1 && here.second == n - 1)
                return true;
            for (int i = 0; i < 4; ++i) {
                pair<int, int> there = {here.first + dx[i], here.second + dy[i]};
                if (!isRange(there.first, there.second))
                    continue;
                if (visited[there.first][there.second])
                    continue;
                if (board[there.first][there.second] < low || board[there.first][there.second] > low + k)
                    continue;
                q.push(there);
                visited[there.first][there.second] = true;
            }
        }
    }
    return false;
}

int main() {
    cin>>n;
    for(int i=0; i<n; ++i) {
        for(int j=0; j<n; ++j) {
            cin>>board[i][j];
        }
    }
    int lo=-1, hi=200;  //lo=false , hi=true;
    while(lo+1<hi) {
        int mid=(lo+hi)/2;
        if(canGo(0, 0, mid)) {
            hi=mid;
        } else
            lo=mid;
    }
    cout<<hi;
    //std::cout << "Hello, World!" << std::endl;
    return 0;
}

다익스트라

위 / 아래 리미트를 정해놓고 다익스트라를 돌린다

bool isRange(int h, int w) {
    if(h < 0 || w < 0 || h >= n || w >= n) return false;
    else return true;
}


int  isPossible(int limit, const vector<vector<int> > &board) {
    int mmove[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};
    priority_queue<comp> que;
    vector<vector<bool> > visited(n, vector<bool>(n, false));
    que.push(comp(0,0, board[0][0]));
    while(!que.empty()) {
        int nowH = que.top().h;
        int nowW = que.top().w;
        int nowV = que.top().c;
        que.pop();
        if(nowH == n- 1 && nowW == n-1) return nowV;
        for(int i = 0; i < 4; i++) {
            int nextH = nowH + mmove[i][0];
            int nextW = nowW + mmove[i][1];
            if(isRange(nextH, nextW)) {
                int nextV = max(board[nextH][nextW], nowV);
                if(board[nextH][nextW] >= limit && visited[nextH][nextW] == false) {
                    que.push(comp(nextH, nextW, nextV));
                    visited[nextH][nextW] = true;
                }
            }
        }
    }
    return 2000;
}

int main() {
    cin >> n;
    vector<vector<int> > board(n, vector<int>(n));
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            scanf("%d",  &board[i][j]);
        }
    }

    int ans = INF;

    for(int i = 0; i <= board[0][0]; i++) {
        ans = min(isPossible(i, board) - i, ans);
    }
    cout << ans << endl;
}

이상한 사람 풀이

http://codersbrunch.blogspot.com/2016/10/1981.html

#include<cstdio>
#include<algorithm>
using namespace std;
const int fx[] = { 0,1,0,-1 }, fy[] = { 1,0,-1,0 };
int n, cnt, p[10000], r = 999;
pair<int, int> s[10000];
int f(int h) { return h^p[h] ? p[h] = f(p[h]) : h; }
int main() {
    scanf("%d", &n);
    for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) s[cnt].second = i*n + j, scanf("%d", &s[cnt++].first);
    sort(s, s + cnt);
    for (int i = 0; i <= 200; i++) {
        int ck[100][100] = { 0, };
        for (int j = 0; j < n*n; j++) p[j] = j;
        for (int j = 0; j < cnt; j++) if (s[j].first >= i) {
            ck[s[j].second / n][s[j].second%n] = 1;
            for (int k = 0; k < 4; k++) {
                int tx = s[j].second / n + fx[k], ty = s[j].second%n + fy[k];
                if (tx >= 0 && ty >= 0 && tx < n && ty < n && ck[tx][ty]) p[f(tx*n + ty)] = f(s[j].second);
            }
            if (f(0) == f(n*n - 1)) { r = min(r, s[j].first - i); break; }
        }
    }
    printf("%d", r);
    return 0;
}

[jungin]
Written by@[jungin]
안녕하세요

GitHub