Cod sursa(job #2565299)

Utilizator LazarRazvanLazar Razvan LazarRazvan Data 2 martie 2020 13:30:56
Problema Secventa Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.91 kb
#include <iostream>
#include <fstream>
#include <stack>
#include <queue>

#define MARCEL 'M'
#define HAPPYMARCEL 'H'

#define STONE '#'

#define SAND '.'
#define VISITED '*'

#define FOUNTAIN '@'
#define USEFULLFOUNTAIN '^'


using namespace std;

ifstream fin;
ofstream fout;

struct cell
{
    int l, c;
};

struct movement
{
    int l, c;
}d[5];

stack <cell> marcei;
queue < cell > q;

int t;          //nr of tests
int n, m;       //nr of lines and columns
char mat[101][101];

void read();
int solve();
void write();

void initMovement()
{
    d[0].l = 0;
    d[0].c = 1;

    d[1].l = -1;
    d[1].c = 0;

    d[2].l = 0;
    d[2].c = -1;

    d[3].l = 1;
    d[3].c = 0;
}

int main() {

    fin.open("marceland.in");
    fout.open("marceland.out");

    initMovement();

    fin >> t;

    while(t){

        read();

        int addFountain = solve();

        fout << addFountain << '\n';

        if (addFountain != -1)
            write();

        t--;
    }

    fin.close();
    fout.close();
    return 0;


}

void read()
{
        fin >> n >> m;

        for (int l = 0; l < n; l++)
        {
            for (int c = 0; c < m; c++)
            {
                char a;
                fin >> a;

                if (a == MARCEL)
                {
                    cell M{};
                    M.l = l;
                    M.c = c;

                    marcei.push(M);
                }

                mat[l][c] = a;
            }
        }


}

void write()
{

    for (int l = 0; l < n; l++)
    {
        for (int c = 0; c < m; c++)
        {
            if (mat[l][c] == HAPPYMARCEL)
                fout << MARCEL;
            else if (mat[l][c] == USEFULLFOUNTAIN)
                fout << FOUNTAIN;
            else if (mat[l][c] == VISITED)
                fout << SAND;
            else
                fout << mat[l][c];
        }
        fout << '\n';
    }

}

bool check(int l, int c)
{
    if (l > n-1 || l < 0)
        return false;
    if (c > m-1 || c < 0)
        return false;

    if (mat[l][c] == STONE)
        return false;

    if (mat[l][c] == HAPPYMARCEL)
        return false;
    if (mat[l][c] == VISITED)
        return false;
    if (mat[l][c] == USEFULLFOUNTAIN)
        return false;

    return true;

}

int solve()
{
    int additionalFountains = 0;

    while (!marcei.empty())
    {
        cell M = marcei.top();
        marcei.pop();

        if (mat[M.l][M.c] == MARCEL)
        {
            mat[M.l][M.c] = HAPPYMARCEL;

            q.push(M);

            bool existsFountain = false;
            cell lastSand = {-1,-1};

            while(!q.empty())
            {
                cell cCell = q.front();
                q.pop();

                int cL = cCell.l;
                int cC = cCell.c;

                if (mat[cL][cC] == SAND)
                {
                    lastSand.c = cC;
                    lastSand.l = cL;
                    mat[cL][cC] = VISITED;
                }

                if (mat[cL][cC] == MARCEL)
                {
                    mat[cL][cC] = HAPPYMARCEL;
                }

                if (mat[cL][cC] == FOUNTAIN)
                {
                    existsFountain = true;
                    mat[cL][cC] = USEFULLFOUNTAIN;
                }

                //cout << "*";

                for (int i = 0; i < 4; i++)
                {
                    int nL = cL + d[i].l;
                    int nC = cC + d[i].c;

                    if (check(nL, nC))
                    {
                        cell next{};
                        next.l = nL;
                        next.c = nC;

                        q.push(next);
                    }
                }

            }

            if(existsFountain == false)
            {
                if (lastSand.l == -1)
                    return -1;
                mat[lastSand.l][lastSand.c] = USEFULLFOUNTAIN;
                additionalFountains++;
            }
        }
    }

    return additionalFountains;
}