[18] Concurs - Triunghiuri

Re: [18] Concurs - Triunghiuri

Postby Teal » 09 Nov 2011, 15:08

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int *iSegments = NULL, iSolution[3];
  4. long int liCount, liIndex;
  5. int isTriangle(int a, int b, int c)
  6. {
  7.         if(a + b > c && a + c > b && b + c > a) return 1;
  8.         return 0;
  9. }
  10. int main()
  11. {
  12.         freopen("bitcell.in", "r", stdin);
  13.         freopen("bitcell.out", "w", stdout);
  14.         int iValue, iSuma = 0;
  15.         long int a, b, c;
  16.         while(scanf("%d", &iValue) != EOF)
  17.         {
  18.                 liCount++;
  19.                 iSegments = (int *) realloc(iSegments, liCount * sizeof(int));
  20.                 iSegments[liCount - 1] = iValue;
  21.         }
  22.         for(a = 0; a < liCount - 2; a++)
  23.                 for(b = a + 1; b < liCount - 1; b++)
  24.                         for(c = b + 1; c < liCount; c++)
  25.                                 iSuma += isTriangle(iSegments[a], iSegments[b], iSegments[c]);
  26.         printf("%d", iSuma);
  27.         return 0;
  28. }


Poftim cod C.
0,0p / 0 votes
User avatar
Teal
Bit
 
Joined: 26 Jan 2010
Location: Suceava
Status: 0

Re: [18] Concurs - Triunghiuri

Postby new_luca » 09 Nov 2011, 15:33

Dap, pe asta il inteleg :D, este exact cum am facut si eu prima solutie, metoda "Brute Force", doar ca e alocat dinamic vectorul, ce e nasol la solutia asta e ca pe masura ce cresc numerele din fisierul de intrare sta "zeci de ani" sa calculeze, banuiesc ca nu e chiar implementarea din C++ de mai devreme pentru ca nu e nici un Backtracking, nu ca l-as intelege prea bine dar nu vad nimic de genul.

Ia uite-te la solutia scrisa de Payne si cea in C scrisa de mine, calculeaza relativ instant rezultatul si pentru un milion de numere.
Banuiesc ca si metodei backtracking ii ia mai mult timp sa calculeze, nu ?
0,0p / 0 votes
Image
User avatar
new_luca
Byte
 
Joined: 03 Jul 2011
Location: Gaesti
Status: 12

Re: [18] Concurs - Triunghiuri

Postby cata45 » 09 Nov 2011, 15:47

@new_luca Daca foloseste back la problema asta nu e vorba de "rezultat afisat instant" sau in cateva secunde ci de minute intregi (As putea spune ca poate dura si o jumatate de ora pe un test - in functie de cat de optimizat e back-ul si de testul bagat) Poate la urmatorul concurs imi bag si eu nasul daca am timp... Cine propune urmatorul concurs? (si cand?)
0,0p / 0 votes
The EARTH without ART is just EH.
User avatar
cata45
Byte
 
Joined: 02 Sep 2010
Status: 9

Re: [18] Concurs - Triunghiuri

Postby Mihai » 10 Nov 2011, 00:33

Teal wrote:De ce va complicati unii din voi?

Trebuia sa generati toate combinatiile posibile de N luate cate 3 si sa testati folosind teorema ca suma a oricare doua laturi ale unui triunghi sunt mai mare decat a treia.


Bagă în fișierul de intrare 1000000 de numere egale intre ele și spune-mi și mie în cât timp ți se va termina execuția. Motivul pentru care lumea "se complică" este faptul că soluția banală este total ineficientă; mai mult decât atât, soluția ta este chiar mai proastă decât soluția banală - pentru că folosești recursivitatea, soluția ta se va mișca mai greu decât una iterativă cum este cea implementată de Luca.

Ca și sfat pentru viitor, aveți grijă cum alegeți tipurile de date! În cazul de față, numărul de combinări putea fi unul foarte mare!
0,0p / 0 votes
User avatar
Mihai
Byte
 
Joined: 29 Dec 2009
Status: 25

Re: [18] Concurs - Triunghiuri

Postby Teal » 12 Nov 2011, 17:14

  1. #include <fstream>
  2. typedef unsigned long u;
  3. typedef int i;
  4. u s[101] = { 0 }, n = 0, r;
  5. i a, b, c, j;
  6. u e(u a) { return s[a]; }
  7. i t(i a, i b, i c) { return (a + b > c && a + c > b && b + c > a) ? 1 : 0; }
  8. u f(i n, i s) { r = 1; for(j = s; j <= n; j++) r *= j; return r; }
  9. u cc(i n, i p) { r = f(n, n - p + 1) / f(p, 2); return r; }
  10. u d() {
  11.     for(a = 1; a <= 100; a++) {
  12.         if(e(a)) {
  13.              for(b = a + 1; b <= 100; b++)
  14.                 if(e(b)) for(c = b + 1; c <= 100 && c < a + b; c++)
  15.                     if(e(c)) n += t(a, b, c) * e(a) * e(b) * e(c);
  16.             if(e(a) > 1) {
  17.                 for(b = 1; b < 2 * a && b <= 100; b++)
  18.                     if(e(b) && a != b) n += t(a, a, b) * cc(e(a), 2) * e(b);
  19.                 if(e(a) > 2) n+= cc(e(a), 3);
  20.             }
  21.         }
  22.     }
  23.     std::ofstream f("bitcell18.out");
  24.     f<<n;
  25.     f.close();
  26. }
  27. i main() {
  28.     std::ifstream f("bitcell18.in");
  29.     while(f>>j) s[j]++;
  30.     f.close();
  31.     d();
  32. }
0,0p / 0 votes
User avatar
Teal
Bit
 
Joined: 26 Jan 2010
Location: Suceava
Status: 0

Re: [18] Concurs - Triunghiuri

Postby Mihai » 13 Nov 2011, 00:00

N-am s-o fac totuși pentru că mi se pare o lipsă de respect față de oricine se chinuie să citească ceea ce am vrut să spun și deci postul o să zboare; același lucru care se va întâmpla și cu postul tău dacă nu modifici codul cu unul mai puțin obfuscat (: .
0,0p / 0 votes
User avatar
Mihai
Byte
 
Joined: 29 Dec 2009
Status: 25

Re: [18] Concurs - Triunghiuri

Postby Teal » 13 Nov 2011, 02:20

Where is the love?

  1. #include <fstream>
  2. unsigned long s[101] = { 0 }, n = 0, r;
  3. int a, b, c, j;
  4. // zice de cate ori E segmentul respectiv in lista
  5. unsigned long e(unsigned long a) { return s[a]; }
  6. // zice daca e un Triunghi
  7. int t(int a, int b, int c) { return (a + b > c && a + c > b && b + c > a) ? 1 : 0; }
  8. // calculeaza un fel de Factorial pornind de la s si nu de la 2
  9. unsigned long f(int n, int s) { r = 1; for(j = s; j <= n; j++) r *= j; return r; }
  10. // Calculeaza numarul de Combinatii
  11. unsigned long cc(int n, int p) { r = f(n, n - p + 1) / f(p, 2); return r; }
  12. // calculeaza numarul de triunghiuri (Do)
  13. unsigned long d() {
  14.     for(a = 1; a <= 100; a++) {
  15.         if(e(a)) {
  16.              for(b = a + 1; b <= 100; b++)
  17.                 if(e(b)) for(c = b + 1; c <= 100 && c < a + b; c++)
  18.                     if(e(c)) n += t(a, b, c) * e(a) * e(b) * e(c);
  19.             if(e(a) > 1) {
  20.                 for(b = 1; b < 2 * a && b <= 100; b++)
  21.                     if(e(b) && a != b) n += t(a, a, b) * cc(e(a), 2) * e(b);
  22.                 if(e(a) > 2) n+= cc(e(a), 3);
  23.             }
  24.         }
  25.     }
  26.     std::ofstream f("bitcell18.out");
  27.     f<<n;
  28.     f.close();
  29. }
  30. int main() {
  31.     std::ifstream f("bitcell18.in");
  32.     while(f>>j) s[j]++;
  33.     f.close();
  34.     d();
  35. }

Literele scrise capitalizat din comentarii arata de ce functiile au fost denumite asa.
0,0p / 0 votes
User avatar
Teal
Bit
 
Joined: 26 Jan 2010
Location: Suceava
Status: 0

Previous

Return to Concursuri de programare desktop

Who is online

Users browsing this forum: No registered users and 0 guests

cron