👤
Pinaplepie
a fost răspuns

Este anul 2019, dar Zmeul-Cel-Rău și Făt-Frumos luptă în continuare. Zmeul l-a prins pe Făt-Frumos şi l-a închis în una dintre camerele bârlogului său. Un bârlog de zmeu are forma unui tablou bidimensional, în care camerele sunt plasate sub forma a n linii și m coloane. Vom numerota liniile de la 1 la n, iar coloanele de la 1 la m, astfel că fiecare cameră poate fi identificată prin numărul liniei și al coloanei pe care se află. Orice cameră are patru pereți și câte o ușă pe fiecare perete prin care poate comunica cu camerele învecinate. Mai exact, camera de pe linia i și coloana j poate comunica cu camerele (i-1,j), (i,j+1), (i+1,j), (i,j-1) (desigur, dacă acestea există). Fiecare cameră are asociat un cod. Ușile din orice cameră se pot deschide cu o cartelă magnetică. Dacă codul camerei este un subșir al cuvântului memorat pe cartela magnetică, atunci ușile din camera respectivă se vor deschide folosind cartela. Ileana Cosânzeana a reușit să-i trimită lui Făt-Frumos o cartelă magnetică. Cerința Scrieți un program care rezolvă următoarele două cerințe: 1. determină numărul de camere în care ar putea ajunge Făt-Frumos folosind cartela primită de la Ileana Cosânzeana; 2. determină numărul minim de camere prin care trece Făt-Frumos pentru a ieși din bârlogul zmeului (adică poate deschide ușa unei camere prin care ajunge în exteriorul bârlogului). Date de intrare Fișierul de intrare barlog.in conține pe prima linie cerința c care trebuie să fie rezolvată (1 sau 2). Pe a doua linie se află două numere naturale n m, reprezentând numărul de linii și respectiv numărul de coloane ale tabloului care reprezintă bârlogul zmeului. Pe următoarele n linii se află câte m cuvinte, reprezentând în ordine codurile de acces ale camerelor din bârlogul zmeului. Pe ultima linie sunt două numere naturale și un cuvânt lin col cuv, reprezentând linia și coloana camerei în care a fost închis Făt-Frumos, precum și cuvântul înscris pe cartela magnetică primită de Făt-Frumos de la Ileana Cosânzeana. Valorile scrise pe aceeași linie sunt separate prin câte-un spațiu. Date de ieșire Fișierul de ieșire barlog.out va conține o singură linie pe care va fi scris un număr natural determinat conform cerinței c. Restricții și precizări 2 ≤ n, m ≤ 100 Codurile camerelor și cuvântul de pe cartelă sunt cuvinte nevide, formate din maximum 20 de litere mici ale alfabetului englez. Pentru datele de test, Făt-Frumos va putea ieși întotdeauna din bârlogul zmeului. Cuvântul a este un subșir al cuvântului b dacă literele din a se găsesc în b în aceeași ordine. De exemplu arma este un subșir al cuvântului marama, dar nu și al cuvântului tamara. Pentru teste valorând 40% din punctaj cerința este 1. În concurs s-au acordat 10 puncte din oficiu. Aici se acordă pentru testele din exemple.

Răspuns :

Răspuns:

#include<bits/stdc++.h>

#define NMAX 104

#define INF (NMAX * NMAX +10)

#define LGMAX 21

#define ND 4

using namespace std;

ifstream fin("barlog.in");

ofstream fout("barlog.out");

struct poz

{

   int lin, col;

};

int dl[]= {-1,0,1, 0};

int dc[]= { 0,1,0,-1};

char b[NMAX][NMAX][LGMAX];

int d[NMAX][NMAX];

int n, m;

char cuv[LGMAX];

poz start;

poz C[NMAX*NMAX];

int prim, ultim;

int cerinta;

int rez[2]= {1,INF};

void citire();

void bordare();

void rezolvare();

bool trece(char cuv[], char s[]);

int main()

{

   citire();

   bordare();

   rezolvare();

   fout<<rez[cerinta]<<'\n';

   fout.close();

   return 0;

}

void citire()

{

   int i, j;

   fin>>cerinta>>n>>m;

   for (i=1; i<=n; i++)

       for (j=1; j<=m; j++)

           fin>>b[i][j];

   fin>>start.lin>>start.col>>cuv;

   cerinta--;

}

void rezolvare()

{

   poz p;

   int k;

   d[start.lin][start.col]=1;

   C[0]=start;

   prim=ultim=0;

   while (prim<=ultim)

   {

       p=C[prim++];

       if (trece(cuv,b[p.lin][p.col]))

           for (k=0; k<ND; k++)

               if (d[p.lin+dl[k]][p.col+dc[k]]==0)

               {

                   d[p.lin+dl[k]][p.col+dc[k]]=1+d[p.lin][p.col];

                   rez[0]++;

                   ++ultim;

                   C[ultim].lin=p.lin+dl[k];

                   C[ultim].col=p.col+dc[k];

               }

               else if (d[p.lin+dl[k]][p.col+dc[k]]==-1 && rez[1]==INF)

                   rez[1]=d[p.lin][p.col];

   }

}

bool trece(char cuv[], char s[])

{

   int i;

   char *p=cuv;

   for (i=0; s[i]; i++)

   {

       p=strchr(p,s[i]);

       if (p)

           p++;

       else

           return 0;

   }

   return 1;

}

void bordare()

{

   int i;

   for (i=0; i<=m+1; i++)

       d[0][i]=d[n+1][i]=-1;

   for (i=0; i<=n+1; i++)

       d[i][0]=d[i][m+1]=-1;

}

Explicație: