Cod sursa(job #2003874)

Utilizator caesar2001Stoica Alexandru caesar2001 Data 24 iulie 2017 11:58:42
Problema Barbar Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.22 kb
#include <cstdio>
#include <queue>
#include <iostream>

using namespace std;

const int NMAX = 1000;

char v[NMAX+3][NMAX+3];

int a[NMAX+1][NMAX+1];

int r,c;

const int iplus[4] = {0,0,-1,1};
const int jplus[4] = {1,-1,0,0};

struct square
{
    int x,y;
};

/*bool operator<(const square &c,const square &b)
{
    return a[c.x][c.y] < a[b.x][b.y];
}*/


//priority_queue <square> h;

square h[(NMAX+1)*(NMAX+1)+10];

int hsize;

void swap(int a,int b)
{
    square tmp;
    tmp = h[a];
    h[a] = h[b];
    h[b] = tmp;
}

void urca(int p)
{
    if(p == 1)
        return ;
    if(a[h[p].x][h[p].y] > a[h[p/2].x][h[p/2].y])
    {
        swap(p,p/2);
        urca(p/2);
    }
}

void adauga(square s)
{
    h[++hsize] = s;
    urca(hsize);
}

void coboara(int p)
{
    int dest = p;
    if(hsize >= p*2 && a[h[p].x][h[p].y] < a[h[p*2].x][h[p*2].y])
        dest = p*2;
    if(hsize >= p*2+1 && a[h[dest].x][h[dest].y] < a[h[p*2+1].x][h[p*2+1].y])
        dest = p*2+1;
    if(p != dest)
    {
        swap(p,dest);
        coboara(dest);
    }
}

void sterge()
{
    swap(hsize,1);
    h[hsize].x = 0;
    h[hsize].y = 0;
    hsize --;
    if(hsize+1 != 1)
    {
        coboara(1);
    }
}

queue <square> q;

square start,finish;

void makecost()
{
    for(int i = 1;i <= r;i ++)
    {
        for(int j = 1;j <= c;j ++)
        {
            if(v[i][j] == 'D')
                q.push({i,j});
            if(v[i][j] == 'I')
            {
                start = {i,j};
                v[i][j] = '.';
            }
            if(v[i][j] == 'O')
            {
                finish = {i,j};
                v[i][j] = '.';
            }
        }
    }
    while(q.size() > 0)
    {
        square s = q.front();
        q.pop();
        for(int dir = 0;dir < 4;dir ++)
        {
            int x = s.x + iplus[dir];
            int y = s.y + jplus[dir];
            if(v[x][y] == '.' && a[x][y] == 0)
            {
                a[x][y] = a[s.x][s.y] + 1;
                q.push({x,y});
            }
        }
    }

}

bool check[NMAX][NMAX];

bool l[NMAX][NMAX];

void makeanswer()
{
    int minim = 99999999;
    adauga(start);
    while(hsize > 0)
    {
        square s = h[1];
        sterge();

        if(check[s.x][s.y] == 1)
            continue;
        check[s.x][s.y] = 1;
        //printf("%d\n",a[s.x][s.y]);
        if(a[s.x][s.y] < minim)
            minim = a[s.x][s.y];
        //printf("%d %d %d\n",s.x,s.y, a[s.x][s.y]);
        if(s.x == finish.x && s.y == finish.y)
        {
            printf("%d\n",minim);
            return ;

        }
        for(int dir = 0;dir < 4;dir ++)
        {
            int x = s.x + iplus[dir];
            int y = s.y + jplus[dir];
            if( v[x][y] == '.' || v[x][y] == 'D' ){
                adauga({x,y});
            }
        }
    }
    printf("-1\n");
    return;
}

int main()
{
    freopen("barbar.in","r",stdin);
    freopen("barbar.out","w",stdout);
    scanf("%d %d\n",&r,&c);
    for(int i = 1;i <= r;i ++)
    {
        fgets(v[i]+1,NMAX+3,stdin);
        //fputs(v[i],stdout);
    }
    makecost();
    makeanswer();
    return 0;
}