Rezolvare completă PbInfo #2894 Barlog

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.

Exemplul 1:

barlog.in

1
5 4
ana are mere bune
dana cere pere multe
cra ana vrea pere
dar dan nu are
sunt bune pe care
3 2 caravana

barlog.out

7

Exemplul 2:

barlog.in

2
5 4
ana are mere bune
dana cere pere multe
cra ana vrea pere
dar dan nu are
sunt bune pe care
3 2 caravana

barlog.out

2

Explicație

Camerele în care poate intra Făt-Frumos sunt: (3,2), (3,3), (2,2), (3,1), (4,2), (2,1), (4,1). Poate ieși din bârlog prin camera (3,1).

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 Barlog:

//Em. Cerchez
#include <fstream>
#include <cstring>
#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;
}

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 #2894 Barlog

Pe această pagină găsești rezolvarea de 100 de puncte pentru problema #2894 Barlog 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!