Rezolvare completă PbInfo #2352 careu

Gigel a inventat un nou joc, de această dată utilizând un rebus sub forma de tablă pătratică cu n x n căsuțe. Fiecare căsuță conține câte o literă mare din alfabetul englez sau caracterul '.'. Literele formează pe orizontală sau pe verticală cuvinte delimitate prin caractere punct sau prin marginile tablei. Cel care joacă trebuie să determine cuvintele speciale din careu. Punctajul unui cuvânt se calculează ca suma codurilor ASCII ale literelor distincte care apar în acel cuvânt. Punctajul total al jocului se calculează însumând punctajele literelor distincte ale cuvintelor speciale distincte. Un cuvânt special îndeplinește simultan condițiile:

  • este palindrom
  • are lungime maximă relativ la alte cuvinte palindrom

Cerința

Să se scrie un program care sa determine, pentru un careu dat, punctajul maxim și cuvintele care permit obținerea punctajului maxim. Dacă nu există astfel de cuvinte se va afișa valoarea 0.

Date de intrare

Fișierul de intrare careu.in conține pe prima linie un număr natural n reprezentând dimensiunea careului. Următoarele n linii conțin fiecare câte n caractere, neseparate prin spații, reprezentând careul. Ultima linie a fișierului de intrare conține una dintre valorile 1 sau 2 reprezentând cerința.

Date de ieșire

Fișierul de ieșire careu.out conține pentru cerința 1, pe prima linie numărul de cuvinte speciale de valoare maximă găsite, iar pe următoarele linii se vor scrie aceste cuvinte în ordine alfabetică, câte unul pe linie; pentru cerința 2, pe prima linie a fișierului de ieșire se va scrie punctajul maxim determinat.

Restricții și precizări

  • 2 <= n <= 50
  • Cuvintele sunt scrise cu litere mari și lungimea cuvintelor din soluție trebuie să fie cel puțin 2.
  • Pentru cerința 1 se acordă 60% din punctaj, iar pentru cerința 2 se acordă 30% din punctaj
  • În concurs s-au acordat 10 puncte din oficiu; aici se acordă 10 puncte pentru cele trei exemple.

Exemplul 1:

careu.in

3
A.A
B.A
..C
1

careu.out

0

Explicație

Nu există nici un cuvânt special de lungime mai mare sau egală cu 2.

Exemplul 2:

careu.in

10
VERDE.CRIN
DANA.DDDDD
VOI.AOQOA.
NU.AAOTE..
.UBOBU.AIA
EZNGAIETAR
ORIOATZULI
TURN.NNNNN
O.ZZCZZ.IU
ELEGATEL.O
1

careu.out

8
AABAA
AOQOA
DDDDD
EOTOE
EZNZE
NNNNN
UBOBU
ZZCZZ

Explicație

Cerința 1. Au fost determinate 8 cuvinte speciale

Exemplul 3:

careu.in

10
VERDE.CRIN
DANA.DDDDD
VOI.AOQOA.
NU.AAOTE..
.UBOBU.AIA
EZNGAIETAR
ORIOATZULI
TURN.NNNNN
O.ZZCZZ.IU
ELEGATEL.O
2

careu.out

832

Explicație

Cerința 2. Punctajul maxim pentru cele 8 cuvinte speciale este 832.
832 = 65+66+67+68+69+78+79+81+84+85+90
A B C D E N O Q T U Z

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

//Marinel Serban - 2018
#include <fstream>
#include <cstring>

using namespace std;

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

#define NMAX 55

char l[NMAX][NMAX], l_cuv[NMAX * 10 + NMAX][NMAX];  //lista cuvintelor
char linie[NMAX];                       //linie fisier
unsigned int n, n_cuv, l_max, cerinta;  //nr linii date, nr.cuvinte, lung maxima cuvant

bool cauta(char c[NMAX])
{
   unsigned int i;
   for (i = 1; i <= n_cuv; i++)
      if (strcmp(c, l_cuv[i]) == 0) return true;
   return false;
}

void ordonare()
{
   unsigned int i, j;
   for (i = 1; i < n_cuv; i++)
      for (j = i + 1; j <= n_cuv; j++)
         if (strcmp(l_cuv[i], l_cuv[j]) > 0)
            swap(l_cuv[i], l_cuv[j]);
}

bool palindrom(char c[NMAX])
{
   int p, u;
   if (strlen(c) <= 2) return false;
   p = 0;
   u = strlen(c) - 1;
   while (p < u)
   {
      if (c[p] != c[u])  return false;
      p++;
      u--;
   }
   return true;
}

void prelucrare()
{
   char cuv[NMAX];
   unsigned int i, j = 0;

   strcpy(cuv, "");
   strcat(linie, ".");
   for (i = 0; i < strlen(linie); i++)
      if (linie[i] != '.')
         cuv[j++] = linie[i];
      else
      {
         cuv[j] = 0;                  //pun null la sfarsit
         if (palindrom(cuv))          //daca e palindrom
         {
            if (strlen(cuv) > l_max)  //si e mai lung ca celelalte
            {
               l_max = strlen(cuv);   //retin lungimea
               n_cuv = 1;             //am gasit primul palindrom de lungimea asta
               strcpy(l_cuv[1], cuv); //il retin
            }
            else if (strlen(cuv) == l_max && !cauta(cuv))
            {      //daca are aceiasi lungime si NU l-am mai pus
               n_cuv++;                   //il numar
               strcpy(l_cuv[n_cuv], cuv); //il retin
            }
         }
         strcpy(cuv, "");             //reinitializez cuv pentru alt cuvant
         j = 0;
      }
}

void princ()
{
   unsigned int i, j;

   fin >> n; fin.get();
   for (i = 1; i <= n; i++)
   {
      fin.getline(l[i], n + 1);   //citesc linia
      strcpy(linie, l[i]);        //o copiez in linia de prelucrare
      prelucrare();               //...
   }
   for (j = 0; j < n; j++) //prelucrare coloane
   {
      strcpy(linie, "");          //formez linia de prelucrare pe cooane
      for (i = 1; i <= n; i++)    //copiez caracter cu caracter
         linie[i-1] = l[i][j];
      linie[i] = 0;               //inchid linia
      prelucrare();               //...
   }
   fin >> cerinta;
}

void scrie()
{
   unsigned int tot, i, j;
   bool este[30];
   char c;

   if (n_cuv == 0)                    //nu am nici un cuvant special detectat
      fout << 0 << '\n';
   else
   {
      ordonare();                     //ordonez cuvintele
      for (c = 'A'; c <= 'Z'; c++)    //resetez vectorul de litere
         este[c-'A'] = false;
      for (i = 1; i <= n_cuv; i++)
         for (j = 0; j < strlen(l_cuv[i]); j++)
            este[l_cuv[i][j]-'A'] = true; //aceasta litera apare
      tot = 0;                        //suma pe 0
      for (c = 'A'; c <= 'Z'; c++)
         if (este[c-'A'])             //daca litera apare
            tot += c;                 //adun codul
      if (cerinta == 1)
      {
         fout << n_cuv << '\n';          //afisari
         for (i = 1; i <= n_cuv; i++)
            fout << l_cuv[i] << '\n';
      }
      else
         fout << tot << '\n';
   }
}

int main()
{
   princ();
   scrie();

   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 #2352 careu

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