Cod sursa(job #2905974)

Utilizator StefanZotaZota Stefan StefanZota Data 24 mai 2022 18:10:20
Problema Barbar Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.71 kb
#include <fstream>
#include <queue>
using namespace std;
ifstream cin("barbar.in");
ofstream cout("barbar.out");
queue<pair<int, int>> q;
int d[1005][1005], dist[1005][1005];
char v[1005][1005];
int nr_lines, nr_cols, start_line, start_col, finish_line, finish_col;
int dx[] = {-1,0,1,0}, dy[] = {0,1,0,-1};
bool inside(int i, int j)
{
    if(i>=1 and i<=nr_lines and j>=1 and j<=nr_cols and v[i][j]!='*' and v[i][j]!='D')
       return true;
    return false;
}
void lee()
{
    for (int index_line = 1; index_line <= nr_lines; index_line++){
        for (int index_col = 1; index_col <= nr_cols; index_col++){  // iteram prin fiecare element din linie
            if (v[index_line][index_col] == '.' || v[index_line][index_col] == 'O' || v[index_line][index_col] == 'I')
                d[index_line][index_col] = (1<<30);  // populam matricea cu valoarea 2^30
            }
        }


    for (int index_line = 1; index_line <= nr_lines; index_line++){
        for (int index_col = 1; index_col <= nr_cols; index_col++){
            if(v[index_line][index_col] == 'D')
            q.push({index_line, index_col});  // stocam in coada q pozitiile dragonilor
        }
        }

    while(q.size()>0)
    {
        int curent_line = q.front().first;
        int current_col = q.front().second;
        q.pop();
        for(int w = 0; w < 4; w++)
        {
            int vecini = curent_line+dx[w];
            int vecinj = current_col+dy[w];
            if(inside(vecini,vecinj) == true && d[vecini][vecinj] > d[curent_line][current_col] + 1)
            {
                d[vecini][vecinj]=d[curent_line][current_col] + 1;  // salvam valoarea +1 in vecinii valizi
                q.push({vecini,vecinj});  //
            }
        }
    }
}
bool check(int x)
{
    for(int index_line = 1; index_line <= nr_lines; index_line++)
    {
        for(int index_col = 1; index_col <= nr_cols; index_col++)
        {
            dist[index_line][index_col] = (1<<30); // populam matricea dist cu valoarea 1<<30 adica 2^30
        }
    }
    q.push({start_line,start_col});
    dist[start_line][start_col] = 0;
    while(q.size() > 0)
    {
        int curent_line = q.front().first;
        int current_col = q.front().second;
        q.pop();
        for(int w = 0; w < 4; w++)
        {
            int vecini = curent_line + dx[w];
            int vecinj = current_col + dy[w];
            if(inside(vecini,vecinj) == true && dist[vecini][vecinj] > dist[curent_line][current_col] + 1 && d[vecini][vecinj] >= x)
            {
                dist[vecini][vecinj]=d[curent_line][current_col]+1;
                q.push({vecini,vecinj});
            }
        }
    }
    if(dist[finish_line][finish_col] != (1<<30))
    {
        return true;
    }
    return false;
}
int main()
{
    cin>>nr_lines>>nr_cols;
    for(int index_line = 1; index_line <= nr_lines; index_line++)
    {
        for(int index_col = 1; index_col <= nr_cols; index_col++)
        {
            cin >> v[index_line][index_col];
            if(v[index_line][index_col] == 'I')
            {
                start_line = index_line;
                start_col = index_col;
            }
            else if(v[index_line][index_col] == 'O')
            {
                finish_line = index_line;
                finish_col = index_col;
            }
        }
    }
    lee();
    int ans = -1;
    int st = 1;
    int dr = d[start_line][start_col];
    while(st <= dr)
    {
        int mij = (st + dr)>>1;
        if(check(mij) == true)
        {
            ans = mij;
            st = mij+1;
        }
        else
        {
            dr = mij-1;
        }
    }
    cout << ans;
    return 0;
}