Cod sursa(job #2132043)

Utilizator SqueekDanielTodasca Daniel SqueekDaniel Data 15 februarie 2018 12:22:10
Problema Barbar Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.65 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#define dimm 1005
const int mval = 100000;

std::ifstream f("barbar.in");
std::ofstream g("barbar.out");

int N, M;
int y0, y, x0, x;
char vis[dimm][dimm];
std::vector <std::pair <int, int>> dragon;

void citire() {
    f >> N >> M;
    char ch;
    for (int i=0, j; i<N; i++)
        for (j=0; j<M; j++) {
            f >> vis[i+1][j+1];
            ch = vis[i+1][j+1];
            if(ch=='.');
            else if(ch=='*');
            else if(ch=='D')
                dragon.push_back(std::pair <int, int> (i+1, j+1));
            else if(ch=='I') y0=i+1, x0=j+1;
            else y=i+1, x=j+1;
        }
}

int dx[] = {1, -1, 0, 0}, dy[]= {0, 0, 1, -1};
struct nod {int y, x;};
int danger[dimm][dimm];
void lee_cost(int y, int x) {
    std::queue <nod> q;
    q.push({y, x});

    nod pres, nou;
    danger[y][x] = 0;
    while(!q.empty()) {
        pres = q.front();
        q.pop();

        for (int i=0; i<4; i++) {
            nou = pres;
            nou.y += dy[i], nou.x += dx[i];

            if(nou.y < 1 || nou.x < 1 || nou.y > N || nou.x > M)
                continue;

            if(vis[nou.y][nou.x] == '.')
                if(danger[nou.y][nou.x] > danger[pres.y][pres.x] + 1)
                    danger[nou.y][nou.x] = danger[pres.y][pres.x] + 1, q.push(nou);
        }
    }
}

bool viz[dimm][dimm];
bool lee(int forta) {
    for (int i=0, j; i<=N+1; i++)
        for (j=0; j<=M+1; j++)
            viz[i][j] = 0;

    std::queue <nod> q;
    q.push({y0, x0});

    nod pres, nou;
    while(!q.empty()) {
        pres = q.front();
        q.pop();

        for(int i=0; i<4; i++) {
            nod nou = pres;
            nou.y += dy[i]; nou.x += dx[i];

            if(nou.y < 1 || nou.x < 1 || nou.y > N || nou.x > M)
                continue;

            if(nou.y == y && nou.x == x)
                return true;

            if(!viz[nou.y][nou.x] && vis[nou.y][nou.x] == '.' && danger[nou.y][nou.x] >= forta)
                viz[nou.y][nou.x] = 1, q.push(nou);
        }
    } return false;
}

void rezolvare() {
    for (int i=0, j; i<=N+1; i++)
        for (j=0; j<=M+1; j++)
            danger[i][j] = mval;
    for (int i=0; i<dragon.size(); i++)
        lee_cost(dragon[i].first, dragon[i].second);

    int st=0, dr=dimm, rez=-1, m;
    while(st<=dr) {
        m = (st+dr)/2;
        bool v = lee(m);

        if(v==0) dr=m-1;
        else rez = std::max(rez, m), st=m+1;
    }
    if(rez == mval) g <<-1;
    else g << rez;
}

int main()
{
    citire();
    rezolvare();

    return 0;
}