Cod sursa(job #2658568)

Utilizator Ionut_neuer58Raducu Ioan Stefan Ionut_neuer58 Data 14 octombrie 2020 13:34:20
Problema Barbar Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.31 kb
#include <iostream>
#include <fstream>
#include <queue>
#include <cmath>

using namespace std;

ifstream in("barbar.in");
ofstream out("barbar.out");

int dy[4]{1, -1, 0, 0}, dx[4]{0, 0, 1, -1};

int manhatt(int ay, int ax, int by, int bx) {return abs(ay-by)+abs(ax-bx);}
int mat[1001][1001], viz[1001][1001];
int ys, xs, yf, xf;
int minn=1000*1000;

struct coord
{
    int y, x;
    bool operator < (const coord other) const
    {
         if(mat[y][x]==mat[other.y][other.x]) return manhatt(y, x, yf, xf)>manhatt(other.y, other.x, yf, xf);
         return mat[y][x]<mat[other.y][other.x];
    }
};

queue <coord> lq;
priority_queue <coord> pq;
coord prev[1001][1001];
int n, m;
char rd;

bool isValid(coord pos) {return pos.y>0 && pos.x>0 && pos.y<=n && pos.x<=m;}

void coutmat(int mat[][1001])
{
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=m; j++)
            cout<<mat[i][j]<<' ';
        cout<<'\n';
    }
    cout<<'\n';
}

void readit()
{
    in>>n>>m;
    for(int i=1; i<=n; i++)
        for(int j=1; j<=n; j++)
        {
            in>>rd;
            if(rd=='D') lq.push({i, j}), mat[i][j]=1;
            else if(rd=='I') ys=i, xs=j, pq.push({ys, xs});
            else if(rd=='O') yf=i, xf=j;
            else if(rd=='*') mat[i][j]=-1;
        }
}

void Lee()
{
    coord now, nxt;
    while(!lq.empty())
    {
        now=lq.front(), lq.pop();
        for(int i=0; i<4; i++)
        {
            nxt=now, nxt.y+=dy[i], nxt.x+=dx[i];
            if(isValid(nxt) && !mat[nxt.y][nxt.x])
                mat[nxt.y][nxt.x]=mat[now.y][now.x]+1, lq.push(nxt);
        }
    }
}

void Astar()
{
    coord now, nxt;
    while(!pq.empty())
    {
        now=pq.top(), pq.pop();
        if(now.y==yf && now.x==xf) return;
        for(int i=0; i<4; i++)
        {
            nxt=now, nxt.y+=dy[i], nxt.x+=dx[i];
            if(isValid(nxt) && mat[nxt.y][nxt.x]!=-1 && !viz[nxt.y][nxt.x])
                pq.push(nxt), prev[nxt.y][nxt.x]=now, viz[nxt.y][nxt.x]=1;
        }
    }
}

void traceback()
{
    coord nav={yf, xf};
    while(nav.y!=ys || nav.x!=xs) minn=min(minn, mat[nav.y][nav.x]), nav=prev[nav.y][nav.x], viz[nav.y][nav.x]=2;
}

int main()
{
    readit();
    Lee();
    Astar();
    traceback();
    out<<minn-1;
    return 0;
}