| Author |
Message |
|
miculprogramator
C++ programmer
Joined: Sat Sep 27, 2008 7:17 pm Posts: 2436 Location: Doesn't matter, I'm runnin'
|
 [ 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 |
|
 |
|
Andrey09
New Member
Joined: Mon Feb 09, 2009 11:23 pm Posts: 45 Location: Galati
|
 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 |
|
 |
|
miculprogramator
C++ programmer
Joined: Sat Sep 27, 2008 7:17 pm Posts: 2436 Location: Doesn't matter, I'm runnin'
|
 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 |
|
 |
|
Andrey09
New Member
Joined: Mon Feb 09, 2009 11:23 pm Posts: 45 Location: Galati
|
 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 |
|
 |
|
Andrewboy
Braincode Programmer
Joined: Wed Aug 01, 2007 5:40 pm Posts: 1363 Location: Botosani
|
 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 |
|
 |
|
moon
New Member
Joined: Thu Jan 28, 2010 12:08 am Posts: 54 Location: Tulcea
|
 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 |
|
 |
|
miculprogramator
C++ programmer
Joined: Sat Sep 27, 2008 7:17 pm Posts: 2436 Location: Doesn't matter, I'm runnin'
|
 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 |
|
 |
|
moon
New Member
Joined: Thu Jan 28, 2010 12:08 am Posts: 54 Location: Tulcea
|
 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 |
|
 |
|
RoCky
Grand Member
Joined: Fri Jan 02, 2009 7:06 pm Posts: 342
|
 Re: [ Clasa X ] Reteta
Sau Code: if (c-'0'<=9) return c-'0'; return 10;
|
| Wed Feb 10, 2010 3:05 pm |
|
 |
|
moon
New Member
Joined: Thu Jan 28, 2010 12:08 am Posts: 54 Location: Tulcea
|
 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 |
|
 |
|
RoCky
Grand Member
Joined: Fri Jan 02, 2009 7:06 pm Posts: 342
|
 Re: [ Clasa X ] Reteta
Nu parcurgi bine sirul. Code: for(i=0;i<strlen(v);i++) { ... }
|
| Wed Feb 10, 2010 4:20 pm |
|
 |
|
moon
New Member
Joined: Thu Jan 28, 2010 12:08 am Posts: 54 Location: Tulcea
|
 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 |
|
 |
|
RoCky
Grand Member
Joined: Fri Jan 02, 2009 7:06 pm Posts: 342
|
 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 |
|
 |
|
miculprogramator
C++ programmer
Joined: Sat Sep 27, 2008 7:17 pm Posts: 2436 Location: Doesn't matter, I'm runnin'
|
 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 |
|
 |
|
astan
Moderator
Joined: Mon Mar 17, 2008 1:22 am Posts: 875
|
 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 |
|
 |
|
miculprogramator
C++ programmer
Joined: Sat Sep 27, 2008 7:17 pm Posts: 2436 Location: Doesn't matter, I'm runnin'
|
 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 |
|
 |
|
astan
Moderator
Joined: Mon Mar 17, 2008 1:22 am Posts: 875
|
 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 |
|
 |
|
tw8
Moderator
Joined: Fri Jul 27, 2007 3:54 pm Posts: 610
|
 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 |
|
 |
|
moon
New Member
Joined: Thu Jan 28, 2010 12:08 am Posts: 54 Location: Tulcea
|
 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 |
|
 |
|
RoCky
Grand Member
Joined: Fri Jan 02, 2009 7:06 pm Posts: 342
|
 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 |
|
 |
|
moon
New Member
Joined: Thu Jan 28, 2010 12:08 am Posts: 54 Location: Tulcea
|
 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 |
|
|
Page 1 of 1
|
[ 21 posts ] |
|
| Google Search |
| | Donate |
|---|
|
| Google Ads |
|
| Global Announcements |
|
| Programming Contests |
|
| Newsletter |
|
| Hackpedia RSS |
|
| Hackpedia's Partners |
|
|