Cod sursa(job #2073720)

Utilizator gundorfMoldovan George gundorf Data 23 noiembrie 2017 16:46:09
Problema Barbar Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.44 kb
#include <iostream>
#include <fstream>
#define Nmax 1010
#include <queue>
using namespace std;
ifstream fin("barbar.in");
ofstream fout("barbar.out");

int a[Nmax][Nmax],n,m;
int xP,yP;// coordonatele punctului de placare a lui Paftenie
int xF,yF;// coordonatele finale
int dl[]= {0,0,1,-1};
int dc[]= {1,-1,0,0};
struct coordonate
{
    int x,y;

} dragoni[Nmax]; //vector de coordonate al dragonilor
int k;
void Citire ()
{
    int i,j;
    char c;
    fin>>n>>m;
    for (i = 1 ; i <= n ; i++)
        for (j = 1 ; j <= m ; j++)
        {
            fin>>c;
            if (c == '*') a[i][j]=-1;//codificare pentru perete
            if (c == 'D')
            {
                a[i][j]=-2;//codificare pentru dragoni
                k++ ;
                dragoni[k].x = i;
                dragoni[k].y = j ;
            }
            if (c=='I')
            {
                xP=i;
                yP=j;
            }
            if (c=='O')
            {
                xF=i;
                yF=j;
            }


        }
}

void Initializare_Matrice_Fata_de_Dragoni (int  a[Nmax][Nmax],int n,int m,coordonate dragoni[],int k)
{
    int i,l,c,lv,cv;

    queue<int> c1,c2;

    for (i=1; i<=k; i++) //introduc toti dragonii in coada ca sa pornesc de la toti concomitent si sa obtin distante minime in matrice
    {
        c1.push(dragoni[i].x);
        c2.push(dragoni[i].y);

    }

    while (!c1.empty()) // lee clasic
    {
        l = c1.front() ;
        c1.pop();
        c = c2.front();
        c2.pop();

        for (i=0; i<4; i++)
        {
            lv=l+dl[i];
            cv=c+dc[i];
            if (lv>=1&&lv<=n&&cv>=1&&cv<=m&&a[lv][cv]==0)
            {
                if (a[l][c] == -2) a[lv][cv] = 1 ;
                else a[lv][cv] = a[l][c] + 1 ;
                c1.push(lv);
                c2.push(cv);
            }

        }

    }

}


int Lee_Dupa_X (int a[Nmax][Nmax],int n,int m,int x)//x e valoarea pe care se poate misca in matrice
{
    int i,l,c,lv,cv;
    bool viz[Nmax][Nmax];
    queue<int> c1,c2;

    c1.push(xP);//adaug pozitia de start in coada
    c2.push(yP);

    while (!c1.empty())
    {
        l = c1.front() ;
        c1.pop();
        c = c2.front();
        c2.pop();

        for (i=0; i<4; i++)
        {
            lv=l+dl[i];
            cv=c+dc[i];
            if (lv>=1&&lv<=n&&cv>=1&&cv<=m&&a[lv][cv]>=x&&viz[lv][cv]==0)
            {
                viz[lv][cv]=1;
                if (lv==xF&&cv==yF) return 1; //daca am ajuns la pozitia de final inseamna ca a existat un drum
                c1.push(lv);
                c2.push(cv);
            }

        }

    }

    return 0;
}


int Cautare_Binar_Solutie (int s,int d)
{
    int last,middle;

    while (s<=d)
    {
        middle=(s+d)/2;
        if (Lee_Dupa_X(a,n,m,middle)==1)
        {
            last=middle;
            s=middle+1;
        }
        else d=middle-1;;
    }

    return last;
}
int main()
{
    int i,j;
    Citire();
    Initializare_Matrice_Fata_de_Dragoni(a,n,m,dragoni,k);

    /*for (i=1; i<=n; i++)
    {
        for (j=1; j<=m; j++)
            fout<<a[i][j]<<" ";
        fout<<"\n";
    }*/
    fout<<Cautare_Binar_Solutie(1,a[xF][yF]);//e clar ca distanta minima fata de dragoni e bottlnecked de distanta punctul de sosire fata de dragoni, fiindca e obligatoriu sa treaca pe acolo

    return 0;
}