Cod sursa(job #2299384)

Utilizator MatteoalexandruMatteo Verzotti Matteoalexandru Data 9 decembrie 2018 14:27:02
Problema Barbar Scor 40
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.31 kb
#include <fstream>
#include <deque>
using namespace std;
ifstream in ("barbar.in");
ofstream out ("barbar.out");
const int NrDir = 4;

struct mat
{
    int linie,coloana;
};
int a[1005][1005],p[1005][1005];
int n,m,i,j,x,k,Max,Il,Ic;
char ch;
deque <int> dl;
deque <int> dc;
void citire()
{
    in>>n>>m;
    for(i=1; i<=n; i++)
    {
        for(j=1; j<=m; j++)
        {
            in>>ch;
            if(ch == '*') p[i][j] = a[i][j] = -2;
            else if(ch == 'D')   /// folosesc o coada
            {
                p[i][j] = a[i][j] = -1;
                dl.push_back(i);
                dc.push_back(j);
                x++;
            }
            else if(ch == 'I')
            {
                p[i][j] = a[i][j] = -3;
                Il = i;
                Ic = j;
            }
            else if(ch == 'O') p[i][j] = a[i][j] = -4;
        }
    }
}
void bordare()
{
    for(i=0; i<=n+1; i++)
        p[0][i] = p[m+1][i] = -10;
    for(i=0; i<=m+1; i++)
        p[i][0] = p[i][n+1] = -10;
}
void generare() /// generez matricea
{
    int cnt=1;
    int dirl[4]= {-1,0,1,0};
    int dirc[4]= {0,1,0,-1};
    int lin,col;
    do
    {
        lin = dl[0];
        col = dc[0];
        for(k=0; k<NrDir; k++)
        {
            if(p[lin+dirl[k]][col+dirc[k]] == 0)
            {
                if(p[lin][col] != -1) /// daca nu sunt pe poz unui dragon
                    p[lin+dirl[k]][col+dirc[k]] = p[lin][col] + 1; /// p[i][j] = distanta minima catre un dragon
                else
                    p[lin + dirl[k]][col + dirc[k]] = 1;
                dl.push_back(lin+dirl[k]); /// pun in coada
                dc.push_back(col+dirc[k]);
                if(p[lin + dirl[k]][col + dirc[k]] > Max)
                    Max = p[lin + dirl[k]][col + dirc[k]] ;
            }
        }
        dl.pop_front();
        dc.pop_front();
    }
    while(!dl.empty());
} /// vreo 3 ore jumate la functia asta, credits Alex Pacurar :D
bool vizitat[1005][1005];

int Lee(int numar)
{
    dl.clear();
    dc.clear();
    for(i=1;i<=n;i++)
        for(j=1;j<=m;j++) vizitat[i][j] = 0; /// reinitializari
    int cnt=1;
    int dirl[4]= {-1,0,1,0};
    int dirc[4]= {0,1,0,-1};
    int lin,col;
    dl.push_back(Il);
    dc.push_back(Ic);
    while(!dl.empty() && p[i][j] != -4)
    {
        lin = dl[0];
        col = dc[0];
        for(k=0;k<NrDir;k++)
        {
            if(p[lin + dirl[k]][col + dirc[k]] >= numar && !vizitat[lin + dirl[k]][col + dirc[k]])
            {
                dl.push_back(lin+dirl[k]);
                dc.push_back(col+dirc[k]);
            }
            else if(p[lin + dirl[k]][col + dirc[k]] == -4)
            {
                return numar;
            }
        }
        vizitat[lin][col] = 1;
        dl.pop_front();
        dc.pop_front();
    }
    return -1;
}
int bin_search() /// caut binar numarul
{
    int st,dr,mid,maxx = -1;
    st = 1;
    dr = Max;
    while(st <= dr)
    {
        mid = (st + dr) / 2;
        if(Lee(mid) != -1){
            if(Lee(mid) > maxx)
                maxx = Lee(mid);
            st = mid + 1;
        }
        else dr = mid - 1;
    }
    return maxx;
}
int main()
{
    citire();
    bordare();
    generare();
    out<<bin_search();
    return 0;
}