Cod sursa(job #2163965)

Utilizator SqueekDanielTodasca Daniel SqueekDaniel Data 12 martie 2018 20:46:25
Problema Barbar Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.82 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#define dimm 1005
#define y first
#define x second
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];                           //matricea citita
int danger[dimm][dimm];                         //folosim la lee cu dragoni
std::queue <std::pair <int, int>> dragon;       //din nou la lee cu dragoni

void precalc() {
    for (int i=0, j; i<=N+1; i++)
        for (j=0; j<=M+1; j++)
            danger[i][j] = mval;
}
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(std::pair <int, int> (i+1, j+1)), danger[i+1][j+1] = 0;
            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};
typedef std::pair <int, int> nod;
void lee_danger() {
    nod pres, nou;
    bool vizd[dimm][dimm];
    for (int i=1, j; i<=N; i++) for (j=1; j<=M; j++) vizd[i][j] = 0;

    while(!dragon.empty()) {
        pres = dragon.front();
        dragon.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(!vizd[nou.y][nou.x]) {
                    danger[nou.y][nou.x] = danger[pres.y][pres.x] + 1, dragon.push(nou);
                    vizd[nou.y][nou.x] = 1;
                }
        }
    }
}

bool viz[dimm][dimm];
bool lee(int capacitate) {
    for (int i=1, j; i<=N; i++)
        for (j=1; j<=M; 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] >= capacitate)
                viz[nou.y][nou.x] = 1, q.push(nou);
        }
    } return false;
}

void rezolvare() {
    lee_danger();

    int st=0, dr=10*dimm, rez=-1, m;
    while(st<=dr) {
        m = (st+dr)/2;
        if(!lee(m)) dr=m-1;
        else rez = std::max(rez, m), st=m+1;
    }
    g << rez;
}

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

    return 0;
}