Cod sursa(job #1537814)

Utilizator OpportunityVlad Negura Opportunity Data 28 noiembrie 2015 03:09:19
Problema Barbar Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.67 kb
#include <bits/stdc++.h>
#include <iostream>
#include <fstream>
#include <queue>
#include <stdio.h>
#define pb push_back
#define mp make_pair
#define fs first
#define sc second
using namespace std;

ifstream fi("barbar.in");
ofstream fo("barbar.out");

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

int n,m,a[1001][1001],isDragon[1001][1001],high,low;
bool viz[1001][1001];
char ch;
pair<int,int> start,finish;
deque< pair<int,int> > q;

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

bool bfs(int bound) {
    q = {};
    memset(viz,0,sizeof(viz));

    if (a[start.fs][start.sc] >= bound) {
        q.pb(mp(start.fs, start.sc));
        viz[start.fs][start.sc] = 1;
    }

    while (!q.empty()) {
        pair<int,int> aux = q.front();
        q.pop_front();
        for (int i = 0; i < 4; ++i) {
            int nx = aux.fs + dx[i];
            int ny = aux.sc + dy[i];
            if (inside(nx, ny) && a[nx][ny] >= bound && !viz[nx][ny]) {
                if (nx == finish.fs && ny == finish.sc) {
                    return true;
                }
                q.pb(mp(nx,ny));
                viz[nx][ny] = 1;
            }
        }
    }

    return false;
}

int bsearch(int low, int high) {
    int mid = (high+low)/2;
    if (low == high) {
        if (bfs(low)) {
            return low;
        } else {
            return low-1;
        }
    }
    if (bfs(mid)) {
        return bsearch(mid+1, high);
    } else {
        return bsearch(low, mid-1);
    }
}

int main() {

    fi >> n >> m;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            fi >> ch;
            switch (ch) {
                case 'I':
                    start.fs = i;
                    start.sc = j;
                    break;
                case 'O':
                    finish.fs = i;
                    finish.sc = j;
                    break;
                case 'D':
                    q.pb(mp(i,j));
                    isDragon[i][j] = 1;
                    break;
                case '*':
                    a[i][j] = -1;
                    break;
                default:
                    break;
            }
        }
    }

    while (!q.empty()) {
        pair<int,int> aux = q.front();
        q.pop_front();
        for (int i=0; i<4; i++) {
            int nx = aux.fs + dx[i];
            int ny = aux.sc + dy[i];
            if (inside(nx, ny) && !isDragon[nx][ny] && a[nx][ny] == 0) {
                a[nx][ny] = a[aux.fs][aux.sc]+1;
                q.pb(mp(nx, ny));
            }
        }
    }

    if (!bfs(-1)) {
        fo << -1;
    } else {
        fo << bsearch(low, a[start.fs][start.sc]);
    }

    return 0;
}