Rezolvare completă PbInfo #1098 Reteta

Mama mea este profesoară de informatică, dar îi place foarte mult să gătească. Recent am descoperit caietul ei de reţete, care arată foarte neobişnuit. Fiecare reţetă este scrisă pe un singur rând pe care sunt precizate produsele folosite, cantităţile, precum şi ordinea în care se execută operaţiile. De exemplu:
(unt 50 zahar 250 ou 4)5
ceea ce înseamnă că se amestecă 50 grame unt cu 250 grame zahăr şi cu 4 ouă timp de 5 minute. Pentru fiecare produs mama foloseşte întotdeauna aceeaşi unitate de măsură, aşa că unităţile de măsură nu mai sunt precizate. Numele produsului este scris întotdeauna cu litere mici, iar produsele şi cantităţile sunt separate prin spaţii (unul sau mai multe). Produsele care se amestecă împreună sunt încadrate între paranteze rotunde; după paranteza rotundă închisă este specificat timpul de preparare.

Evident, mama are şi reţeţe mai complicate:
(((zahar 100 ou 3)5 unt 100 nuca 200)4 (lapte 200 cacao 50 zahar 100) 3)20

Să traducem această reţetă: se amestecă 100 grame zahăr cu 3 ouă timp de cinci minute; apoi se adaugă 100 grame unt şi 200 grame nucă, amestecând totul încă 4 minute. Se amestecă 200 ml lapte cu 50 grame de cacao şi 100 grame zahăr timp de 3 minute, apoi se toarnă peste compoziţia precedentă şi se amestecă totul timp de 20 minute.

Observaţi că înainte sau după parantezele rotunde pot să apară sau nu spaţii.

Cerinţă

Dată fiind o reţetă să se determine timpul total de preparare, precum şi cantităţile necesare din fiecare produs.

Date de intrare

Fişierul de intrare reteta.in conţine pe prima linie un şir de caractere care reprezintă o reţetă.

Date de ieşire

Fişierul de ieşire reteta.out va conţine pe prima linie timpul total necesar pentru prepararea reţetei. Pe următoarele linii sunt scrise ingredientele în ordine lexicografică (ordinea din dicţionar), câte un ingredient pe o linie. Pentru fiecare ingredient este specificat numele urmat de un spaţiu apoi de cantitatea totală necesară.

Restricţii şi precizări

  • 0 < Lungimea unei reţete ≤ 1000
  • 1 ≤ Numărul de ingrediente ≤ 100
  • Numele unui ingredient este scris cu maxim 20 litere mici ale alfabetului englez.
  • Timpii de preparare sunt numere naturale < 100
  • Cantităţile specificate în reţete sunt numere naturale < 1000

Exemplu

reteta.in

(((zahar 100 ou 3)5 unt 100 nuca 200)4 (lapte 200 cacao 50 zahar 100) 3)20

reteta.out

32
cacao 50
lapte 200
nuca 200
ou 3
unt 100
zahar 200

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

#include <fstream>
#include <cstring>
using namespace std;
ifstream fin("reteta.in");
ofstream fout("reteta.out");
 
int main(){
    char s[1001],nume[101][21];
    int cantitate[101],nri=0;
    fin.getline(s,1001);
    int durata = 0;
    for(int i=0;s[i];++i){
        if(s[i]>='a' && s[i]<='z'){
            //incepe un cuvant
            char c[21]="";int lc=0;
            while(s[i]>='a' && s[i]<='z')
                c[lc++] = s[i++], c[lc]=0;
            while(s[i]==' ')
                i++;
            int tt=0;
            while(s[i]==' ') i++;
            while(s[i]>='0' && s[i]<='9')
                tt= 10*tt+s[i]-'0', i++;
            i--;
             
            int poz = 0;
            for(int j=1 ; j<=nri && poz==0 ; ++j)
                if(strcmp(c,nume[j])==0)
                    poz=j;
            if(poz!=0)
                cantitate[poz] += tt;
            else{
                nri++ ;
                strcpy(nume[nri], c);
                cantitate[nri]=tt;
            }
             
        }
        if(s[i]==')'){
            int tt=0;
            i++;
            while(s[i]==' ') i++;
            while(s[i]>='0' && s[i]<='9')
                tt= 10*tt+s[i]-'0', i++;
            //fout<<tt<<" ";
            durata += tt;
            i--;
        }
    }
    fout<<durata<<endl;
     
    for(int i=1;i<nri;++i)
        for(int j=i+1;j<=nri;++j)
            if(strcmp(nume[i],nume[j])>0){
                char a[21]; strcpy(a,nume[i]); strcpy(nume[i], nume[j]); strcpy(nume[j],a);
                int x=cantitate[i]; cantitate[i]=cantitate[j], cantitate[j]=x;
            }
     
    for(int i=1;i<=nri;++i)
        fout<<nume[i]<<" "<<cantitate[i]<<endl;
    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 #1098 Reteta

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