Rezolvare completă PbInfo #885 Imperii

Cerința

Harta unei galaxii îndepărtate are forma unei matrice cu n linii și m coloane, în care fiecare element corespunde unei planete. Unele planete sunt locuibile, altele sunt afectate de radiații nucleare și nu pot fi locuite. Deplasarea prin galaxie se poate face doar de la o planetă la alta, cu condiția să fie ambele locuibile și să se învecineze pe linie sau pe coloană (teleportarea și zborul hiperluminic nu au fost încă inventate).

În această galaxie există patru imperii, având ca nume litere mari diferite ale alfabetului englez, iar capitalele lor sunt situate în cele patru colțuri ale matricei. Ele își dispută din cele mai vechi timpuri controlul planetelor locuibile din galaxie, dar acum au ajuns la un acord: fiecare imperiu va controla planetele locuibile situate față de el la o distanță mai mică decât față de celelalte trei imperii. Dacă o planetă se află la aceeași distanță minimă față de două sau mai multe imperii, ea va rămâne necontrolată de niciun imperiu. Planetele nelocuibile nu fac parte din niciun imperiu. Prin distanța dintre două planete se înțelege distanța minimă dintre ele.

Afișați harta galaxiei în care planetele sunt marcate în conformitate cu imperiul care le controlează.

Date de intrare

Fișierul de intrare imperii.in conține pe prima linie numerele n m. Urmează n linii cu câte m caractere, reprezentând harta imperiului. Caracterele pot fi: -, pentru o planetă locuibilă, #, pentru o planetă nelocuibilă, respectiv patru litere mari distincte ale alfabetului englez, pentru cele patru imperii.

Date de ieșire

Fișierul de ieșire imperii.out va conține n linii, fiecare cu câte m caractere, reprezentând harta imperiului, în care planetele controlate de un anumit imperiu sunt marcate cu litera corespunzătoare acestuia.

Restricții și precizări

  • 1 ≤ n , m ≤ 1000

Exemplu

imperii.in

5 7 
D-#---Y
-------
##--#--
--#---#
M-----A

imperii.out

DD#YYYY
DDD-YYY
##D-#-Y
MM#-AA#
MMM-AAA

Cum e corect?

cout < "As la info"; cout << "As la info"; cout >> "As la info";

Felicitări! Poți mai mult?

Avem sute de probleme pentru tine, fiecare cu explicații ușor de înțeles.

Greșit, dar nu-i bai!

Antrenează-te cu sutele de probleme pe care ți le-am pregătit. Îți explicăm fiecare problemă în parte.

Rezolvare

Iată rezolvarea de 100 de puncte pentru problema Imperii:

#include <iostream>
#include <fstream>
#include <cassert>
using namespace std;

ifstream fin("imperii.in");
ofstream fout("imperii.out");

int n , m;
int a[4][1005][1005];
short  x[1000005], y[1000005];
char P[1005][1005], Imp[5];


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

void fill (int i ,int j , int d)
{
    int st , dr;
    st = dr = 1;
    x[1] = i , y[1] = j;
    a[d][i][j] = 1;
    
    while(st <= dr)
    {
        int i = x[st], j = y[st];
        for(int k = 0 ; k < 4 ; k ++)
        {
            int ii = i + dx[k], jj = j + dy[k];
            if( ii > 0 && ii <= n && jj > 0 && jj <= m && P[ii][jj] !='#' && a[d][ii][jj] == 0)
            {
                a[d][ii][jj] = a[d][i][j] + 1;
                dr ++;
                x[dr] = ii, y[dr] = jj;
            }
        }
        st ++;
    }
}

int main(){
    fin >> n >> m;
    for(int i = 1 ; i <= n ; i ++)
        for(int j = 1 ; j <= m ; j ++)
            fin >> P[i][j];
    Imp[0]=P[1][1];
    Imp[1]=P[1][m];
    Imp[2]=P[n][1];
    Imp[3]=P[n][m];
    fill(1 , 1 , 0);
    fill(1 , m , 1);
    fill(n , 1 , 2);
    fill(n , m , 3);
    
    for(int i = 1 ; i <= n ; i ++)
        for(int j = 1 ; j <= m ; j ++)
        {
            int pmin = 0, ok = 1;
            while(a[pmin][i][j] == 0 && pmin < 4)
                pmin ++;
            if(pmin < 4)
            {
                for(int k =  pmin + 1 ; k < 4 ; k ++)
                    if(a[k][i][j] > 0)
                    {
                        if(a[k][i][j] < a[pmin][i][j])
                            pmin = k , ok = 1;
                        else
                            if(a[k][i][j] == a[pmin][i][j])
                                ok = 0;
                    }
                if(ok)
                    P[i][j] = Imp[pmin];
            }
        }
    for(int i = 1 ; i <= n ; i ++)
    {
        for(int j = 1 ; j <= m ; j ++)
            fout << P[i][j];
        fout << "\n";
    }
    return 0;
}

Atenție

Enunțurile afișate pe această pagină aparțin exclusiv site-ului PbInfo. Astfel, pentru ștergerea conținutului, puteți să ne contactați la adresa Adresa de email.

Rezolvarea problemei #885 Imperii

Pe această pagină găsești rezolvarea de 100 de puncte pentru problema #885 Imperii de pe PbInfo.ro. Atenție: nu încurajăm copiatul codului! Totuși, credem cu tărie că analizarea unei soluții corecte este o metodă foarte ușoară de a învăța informatică, astfel că oferim sursele pentru peste 1500 de probleme de pe platforma PbInfo.ro.

Pentru rezolvări PbInfo de la peste 1500 de probleme, vă invităm să intrați pe site-ul nostru!