It is currently Wed Sep 08, 2010 4:49 am




Post new topic Reply to topic  [ 21 posts ] 
[ Clasa X ] Reteta 
Author Message
C++ programmer
User avatar

Joined: Sat Sep 27, 2008 7:17 pm
Posts: 2436
Location: Doesn't matter, I'm runnin'
Post [ Clasa X ] 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

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
Pentru determinarea corectă a timpului total se acordă 30% din punctajul pe test; pentru determinarea corectă a timpului total şi afişarea corectă a ingredientelor (ordonate lexicografic) se acordă integral punctajul pe test.

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

Timp maxim de execuţie / test: 0.1s
Memorie totala disponibilă/stivă: 2MB / 1MB
Sursa: Olimpiada Judeteana de Informatica 2009
Solutie: in curand
Hint: folositi strtok ()


Wed Jan 27, 2010 7:22 pm
Profile
New Member
User avatar

Joined: Mon Feb 09, 2009 11:23 pm
Posts: 45
Location: Galati
Post Re: [ Clasa X ] Reteta
Uitati si rezolvarea pentru care primiti 100 de puncte

Code:
/* Problema Reteta Rezolvare - Cornescu Andrey - 100p */
#include<fstream>
using namespace std;

struct ingredient
{
   char nume[101];
   int cantitate;
} v[100];

//compararea a doua ingrediente
int compare(const void *x, const void *y)
{
   const ingredient a = *(const ingredient *)x;
   const ingredient b = *(const ingredient *)y;
   
   return strcmp(a.nume, b.nume);
}

int timp_total, i, j, n;

char reteta[1001];

int main()
{
   fstream f("reteta2.in", ios::in);
   fstream g("reteta2.out", ios::out);

   f.get(reteta, 1000);
   
   char buffer[100];

   //adunam timpul
   for(i=0; i < strlen(reteta); i++)
   {
      if(reteta[i] == ')')
      {
         int x = 0;
         for(j=i+1; j < strlen(reteta) && (int)reteta[j] < 65 && reteta[j] != ')' && reteta[j] != '('; j++)
         {
            buffer[x++] = reteta[j];
            buffer[x] = 0;
         }
         
         timp_total += atoi(buffer);
         
         strcpy(reteta + i + 1, reteta+j);
      }
      
      //inlocuim paranteze fiindca nu mai avem nevoie de acestea
      if(reteta[i] == ')' || reteta[i] == '(')
         reteta[i] = ' ';
   }
   
   char *p = strtok(reteta, " ");
   
   while(p)
   {
      // extragerea ingredientului
      char ingredient[100];
      strcpy(ingredient, p);
            
      p = strtok(NULL, " ");
      
      //extragerea timpului
      int cantitate = atoi(p);
      p = strtok(NULL, " ");

      int ok = 0;
      
      //adunam cantitatile daca gasim doua ingrediente cu acelasi nume
      for(i=0; i < n; i++)
         if(strcmp(v[i].nume, ingredient) == 0)
         {
            v[i].cantitate += cantitate;
            ok = 1;
            break;
         }
      
      //altfel adaugam in vector un nou ingredient
      if(!ok)
      {
         strcpy(v[n].nume, ingredient);
         v[n].cantitate = cantitate;
         
         n++;
      }
   }
   
   //tiparire timp total
   g << timp_total << endl;
   
   //sortare ingrediente
   qsort(v, n, sizeof(v[0]), compare);
   
   //tiparire ingrediente
   for(i = 0; i < n; i++)
      g << v[i].nume << " " << v[i].cantitate << endl;
   
   return 0;
}


Fri Jan 29, 2010 12:51 am
Profile
C++ programmer
User avatar

Joined: Sat Sep 27, 2008 7:17 pm
Posts: 2436
Location: Doesn't matter, I'm runnin'
Post Re: [ Clasa X ] Reteta
Nu trebuia sa postezi rezolvarea chiar acum ... Asa cel care va citi problema pentru prima oara se va gandi cum s-o rezolve, dar dupa ce va derula pagina ar vedea ca are 100 de pct la nas.

BTW, eu am folosit strtock() si matrice.


Fri Jan 29, 2010 8:09 am
Profile
New Member
User avatar

Joined: Mon Feb 09, 2009 11:23 pm
Posts: 45
Location: Galati
Post Re: [ Clasa X ] Reteta
mai greu cu sortarea dar merge si cu matici :-? . Am intrebat inainte sa postezi totusi.


Fri Jan 29, 2010 12:03 pm
Profile
Braincode Programmer
User avatar

Joined: Wed Aug 01, 2007 5:40 pm
Posts: 1363
Location: Botosani
Post Re: [ Clasa X ] Reteta
Si cand trebuia sa o posteze!? A mai fost o discutie de genul asta. Daca pui o problema te astepti sa fie si rezolvata nu crezi?! :) Daca nu , numai publici. Daca o rezolva cineva poate o face doar pentru hackpedia si vrea sa o arate si el si sa primeasca idei de optimizare.


Sun Jan 31, 2010 2:54 pm
Profile
New Member
User avatar

Joined: Thu Jan 28, 2010 12:08 am
Posts: 54
Location: Tulcea
Post Re: [ Clasa X ] Reteta
Code:
   for(i=1;i<=sizeof(v);i++)
   {
      while(v[i]!=')')
         i++;
      while(check(v[i])==10)
         i++;
      x=i;
      while(check(v[i])!=10)
         i++;
      y=i-1;
      k=y-x;
      k=1;
      tot=0;
      {
      for(;y>=x;y--)
      {
         tot+=check(v[y])*pow(10,k-1);
         k++;
           
      }
      }
tott+=tot;
      cout<<tot<<'\n';


O varianta mai simpla pentru calculul timpilor...
Insa are o mica problema ce nu stiu de unde provine: la final se citeste un timp in plus,mereu de valoarea 2, asa ca tott va fi in final tott-=2;
Daca reusiti sa depistati problema o sa va rog sa o semnalati !

Add:
Am uitat sa adaug functia:
Code:
int check(char c)
{
   if(c=='0') return 0;
   else if(c=='1') return 1;
   else if(c=='2') return 2;
   else if(c=='3') return 3;
   else if(c=='4') return 4;
   else if(c=='5') return 5;
   else if(c=='6') return 6;
   else if(c=='7') return 7;
   else if(c=='8') return 8;
   else if(c=='9') return 9;
   else return 10;
}


Tue Feb 09, 2010 11:15 pm
Profile
C++ programmer
User avatar

Joined: Sat Sep 27, 2008 7:17 pm
Posts: 2436
Location: Doesn't matter, I'm runnin'
Post Re: [ Clasa X ] Reteta
La functia cu check poti sa pui pur si simplu:

Code:
if (c <= 9)
   return c;
else
   return 10;


:)


Wed Feb 10, 2010 9:19 am
Profile
New Member
User avatar

Joined: Thu Jan 28, 2010 12:08 am
Posts: 54
Location: Tulcea
Post Re: [ Clasa X ] Reteta
Atentie mare miculprogramator ! c este de tipul char si trebuie returnata o valoare de tip intreg !


Wed Feb 10, 2010 2:23 pm
Profile
Grand Member
User avatar

Joined: Fri Jan 02, 2009 7:06 pm
Posts: 342
Post Re: [ Clasa X ] Reteta
Sau
Code:
if (c-'0'<=9)
   return c-'0';
return 10;


Wed Feb 10, 2010 3:05 pm
Profile
New Member
User avatar

Joined: Thu Jan 28, 2010 12:08 am
Posts: 54
Location: Tulcea
Post Re: [ Clasa X ] Reteta
RoCky wrote:
Sau
Code:
if (c-'0'<=9)
return c-'0';
return 10;


Asta merge, insa eu sunt de parere ca varianta simpla este mai sigura.
Mie spre exemplu imi afiseaza un -48 la sfarsit pe implementarea asta, indiferent de sir:
Code:
int check(char c)
{
if (c-'0'<=9)
   return c-'0';
return 10;
}


int main()
{
   char v[101];
   int i;
   ifstream f("sir.in");
   ofstream g("sir.out");
   f.get(v,sizeof(v));
   for(i=1;i<=strlen(v);i++)
      if(check(v[i])!=10) cout<<check(v[i])<<" ";
}


Wed Feb 10, 2010 4:06 pm
Profile
Grand Member
User avatar

Joined: Fri Jan 02, 2009 7:06 pm
Posts: 342
Post Re: [ Clasa X ] Reteta
Nu parcurgi bine sirul.
Code:
for(i=0;i<strlen(v);i++)
{
   ...
}


Wed Feb 10, 2010 4:20 pm
Profile
New Member
User avatar

Joined: Thu Jan 28, 2010 12:08 am
Posts: 54
Location: Tulcea
Post Re: [ Clasa X ] Reteta
Total irelevant. Acel "-48" nu este dat de faptul ca incep sa citesc sirul de la 1.
Asa ca intreb din nou, de ce sa ne complicam cu astfel de lucruri ? De ce sa ne folosim de ASCII cand putem sa implementam lucrurile mult mai simplu, fara sa afectam eficienta functiei ? Rolul functiei mele este extrem de vizibila, iar daca ma folosesc de ceva precum "if (c-'0'<=9)" as putea sa gresesc fara sa imi dau seama si sa ajung sa am probleme la debug. Chiar si daca nu gresesc, pana una alta functia ta imi afiseaza un "-48" ce nu stiu de unde provine.


Wed Feb 10, 2010 5:02 pm
Profile
Grand Member
User avatar

Joined: Fri Jan 02, 2009 7:06 pm
Posts: 342
Post Re: [ Clasa X ] Reteta
Tu nu il citesti de la 1 ci de la 0 numai ca il parcurgi gresit.
Pentru exemplul 22asdjuh4v5jfgt5 iti afiseaza 2455 cand ar trebui sa afiseze 22455.


Wed Feb 10, 2010 6:27 pm
Profile
C++ programmer
User avatar

Joined: Sat Sep 27, 2008 7:17 pm
Posts: 2436
Location: Doesn't matter, I'm runnin'
Post Re: [ Clasa X ] Reteta
RoCky wrote:
Sau
Code:
if (c-'0'<=9)
   return c-'0';
return 10;


Am uitat ca c e char. Asa e ok .

Pe mine ma deranjeaza sa scriu multe if-uri insiruite, daca trebuie neaparat sa verific multe chestii prefer un switch. :)


Wed Feb 10, 2010 10:27 pm
Profile
Moderator

Joined: Mon Mar 17, 2008 1:22 am
Posts: 875
Post Re: [ Clasa X ] Reteta
Code:
if (c-'0'<=9)
   return c-'0';

e gresit.

Code:
for(i=1;i<=strlen(v);i++)
      if(check(v[i])!=10) cout<<check(v[i])<<" ";

e de asemenea gresit


Wed Feb 10, 2010 10:40 pm
Profile
C++ programmer
User avatar

Joined: Sat Sep 27, 2008 7:17 pm
Posts: 2436
Location: Doesn't matter, I'm runnin'
Post Re: [ Clasa X ] Reteta
Asa e bine ? :)

Code:
int caracter (char c)
{
   switch (c)
   {
      case '1' : return 1;
      case '2' : return 2;
      case '3' : return 3;
      case '4' : return 4;
      case '5' : return 5;
      case '6' : return 6;
      case '7' : return 7;
      case '8' : return 8;
      case '9' : return 9;
      default : return -1;
   }
   
}


Thu Feb 11, 2010 12:34 am
Profile
Moderator

Joined: Mon Mar 17, 2008 1:22 am
Posts: 875
Post Re: [ Clasa X ] Reteta
E ok. Poti sa scrii mai scurt:

Code:
int character(char c)
{
   if (c >= '0' && c <= '9')
      return c - '0';
   return -1;
}


Thu Feb 11, 2010 12:43 am
Profile
Moderator

Joined: Fri Jul 27, 2007 3:54 pm
Posts: 610
Post Re: [ Clasa X ] Reteta
Din curiozitate, am incercat sa vad care e cea mai rapida metoda de a extrage cifra dintr-un caracter - daca e cifra. Pentru 100 de milione de executii, folosind macrouri, timpul de executie e de 3 ori mai mic decat in functiile prezentate mai sus:
Code:
#define character3(c)(int)('0'<=c&&c<='9'?c-'0':-1)


Thu Feb 11, 2010 3:24 pm
Profile
New Member
User avatar

Joined: Thu Jan 28, 2010 12:08 am
Posts: 54
Location: Tulcea
Post Re: [ Clasa X ] Reteta
RoCky, pe mine ma deranja acel "-48" (caruia inca nu-i gasesc cauza,asa ca va rog sa o semnalati) nu faptul ca imi sarea peste primul caracter. Eu scrisesem acel cod in graba ca sa vad daca iti functioneaza functia corect.
astan, daca nu ne spui si motivul pentru care sunt gresite acele variante, nu faci decat sa ne incurci.


Thu Feb 11, 2010 4:05 pm
Profile
Grand Member
User avatar

Joined: Fri Jan 02, 2009 7:06 pm
Posts: 342
Post Re: [ Clasa X ] Reteta
Moon nu ai citit ce am scris ?
Tu parcurgi sirul gresit ,de asta iti sarea si primul caracter si de asta afiseaza si -48 pentru ca la sfarsitul sirului( pe pozitiva strlen(v) ) este caracterul NULL care are valoarea 0.


Thu Feb 11, 2010 4:40 pm
Profile
New Member
User avatar

Joined: Thu Jan 28, 2010 12:08 am
Posts: 54
Location: Tulcea
Post Re: [ Clasa X ] Reteta
Nu vazusem acel '<'. Credeam ca te-ai referit doar la faptul ca il incep de la 1.
Insa si tu ai fost "extrem" de clar. Ai fi putut pur si simplu sa-mi spui "nu este '<=' ci '<'.

Uite, cum sa nu ma induca in eroare un astfel de reply ?

Code:
Tu nu il citesti de la 1 ci de la 0 numai ca il parcurgi gresit.
Pentru exemplul 22asdjuh4v5jfgt5 iti afiseaza 2455 cand ar trebui sa afiseze 22455.


1. Il citeam de la 1 insa cum am mai spus, total irelevant.
2. Nu, nu mi-ar afisa '2 4 5 5' ci '2 4 5 5 -48'. Asta m-a facut sa cred ca bati unde nu trebuie.


Thu Feb 11, 2010 4:50 pm
Profile
 
Post new topic Reply to topic  [ 21 posts ] 


Who is online

Users browsing this forum: No registered users and 0 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  
cron
Powered by phpBB © phpBB Group.
Designed by boogiesbc and Vjacheslav Trushkin .