infoarena

infoarena - concursuri, probleme, evaluator, articole => Arhiva de probleme => Subiect creat de: Andrei Grigorean din Decembrie 14, 2008, 14:34:18



Titlul: 782 Densitate
Scris de: Andrei Grigorean din Decembrie 14, 2008, 14:34:18
Aici puteti discuta despre problema Densitate (http://infoarena.ro/problema/densitate).


Titlul: Răspuns: 782 Densitate
Scris de: Catalin Ionescu din Decembrie 14, 2008, 23:02:03
Am si eu o problema cu sursa mea... ideea e ca TLE nu da ... numerele sunt pana la 500.000 ceea ce inseamna ca intra in int... si totusi nu imi da...  :aha: as avea si eu nevoie de un sfat pentru ca am incercat teste gasite pe net cand am cautat teorema numerelor prime :)
"Number of primes < 10^n.
0, 4, 25, 168, 1229, 9592, 78498,"
exact asa imi da... unde gresesc?
Cod:
...


Titlul: Răspuns: 782 Densitate
Scris de: Rus Cristian din Decembrie 14, 2008, 23:07:52
cred ca trebuie sa afisezi x [ b ] - x [ a-1 ] ...


Titlul: Răspuns: 782 Densitate
Scris de: Catalin Ionescu din Decembrie 14, 2008, 23:16:25
de ce? ca fii atent... am editat foru asa...
Cod:
for(i=1;i<=q;++i)
{
scanf("%d%d",&a,&b);
s = x[b] - x[a];
if((c[a] == false) || (c[b] == false) )
s++;
printf("%d\n",s);

}
ca am citit pe celalat topic ca in cazul in care capetele sunt prime se iau si ele in calcul ... si acum am dat toate testele care mi-au trecut prin cap si da bine... unde gresesc?

cred ca trebuie sa afisezi x [ b ] - x [ a-1 ] ...

daca reusesti sa-mi explici de ce rationamentu meu lua 0 puncte si ceea ce mi-ai zis tu sa schimb ia 100 iti ridic statuie :)
 :yahoo:

[edit] nu posta de 2 ori consecutiv, foloseste butonul de editare a mesajului


Titlul: Răspuns: 782 Densitate
Scris de: Rus Cristian din Decembrie 14, 2008, 23:19:33
pai, ideea e urmatoarea...tu retii in x[ i ] cate numere prime ai intre 1 si i deci intre a si b ai un numar de numere prime egal cu
x [ b ] care este numarul de prime in intervalul [1,b] din care scazi x [ a-1 ], care este egal cu numarul de numere prime din intervalul [1,a-1], si raman numerele prime din intervalul [a,b]. Tu facand operatia x [ b ] - x [ a ] calculai numarul de numere prime din intervalul [a+1,b]


Titlul: Răspuns: 782 Densitate
Scris de: Catalin Ionescu din Decembrie 14, 2008, 23:42:09
aaa...  ](*,) e logic :) mersi mult inca odata pentru ajutor :)
apropo... acu eu ar trebui sa scot sursa din primul mesaj sau cu ajutorul a ceea ce ai zis tu toti o sa ia 100 nu? :)


Titlul: Răspuns: 782 Densitate
Scris de: Emanuel Cinca din Decembrie 15, 2008, 17:29:55
cica o sa ai statuie cristi  :shock: =D&gt;

sa-mi zici cand e dezvaluirea :rotfl:


Titlul: Răspuns: 782 Densitate
Scris de: Rus Cristian din Decembrie 15, 2008, 21:01:25
 :ok:


Titlul: Răspuns: 782 Densitate
Scris de: Ioan-Cornel Tamas din Decembrie 16, 2008, 16:21:51
Ciurul lui Eratosthenes nu e suficient de rapid ?? Am incercat cu asta si mi-au iesit 40 puncte, la restul mi-a dat "Time limit exceeded" ... Am vrut si eu sa fac asa, adica sa calculez pentru fiecare numar cate nr prime se afla intre 1 si el, dar am considerat-o mai inceata decat ciurul. E mai inceata sau mai rapida ??? (inca nu am inteles bine complexitatile si optimizarile, dar invat pe parcurs :) ) ....


Titlul: Răspuns: 782 Densitate
Scris de: Emanuel Cinca din Decembrie 16, 2008, 16:42:46
cand ai nevoie de mai multe numere, ciurul isi face foarte bine treaba... doar ca aici nu ai nevoie doar de ciur...trebuie sa-ti mai dai seama de ceva... dar numerele prime tot cu ciurul le calculezi... daca nu te descurci poti sa te uiti in articolul cu solutii :peacefingers:


Titlul: Răspuns: 782 Densitate
Scris de: Andrei Misarca din Decembrie 16, 2008, 16:49:34
daca nu te descurci poti sa te uiti in articolul cu solutii :peacefingers:
Unde se poate gasi?  :D


Titlul: Răspuns: 782 Densitate
Scris de: Emanuel Cinca din Decembrie 16, 2008, 17:00:03
nu e tot, dar http://infoarena.ro/algoritmiada-2009/runda-1/solutii


Titlul: Răspuns: 782 Densitate
Scris de: Feier Vlad din Decembrie 16, 2008, 18:40:24
cand ai nevoie de mai multe numere, ciurul isi face foarte bine treaba... doar ca aici nu ai nevoie doar de ciur...trebuie sa-ti mai dai seama de ceva... dar numerele prime tot cu ciurul le calculezi... daca nu te descurci poti sa te uiti in articolul cu solutii :peacefingers:
Da, adica faci preprocesare si trimiti sursa cu un vector v[500000], unde v[i ] = nr de nr prime pana la i. Cu asta ai rezolvat problema in O(n). Bad point: sursa cam mare (multi KB), s-ar putea sa n-o primeasca.


Titlul: Răspuns: 782 Densitate
Scris de: Emanuel Cinca din Decembrie 16, 2008, 18:55:54
Citat
Da, adica faci preprocesare si trimiti sursa cu un vector v[500000], unde v[i ] = nr de nr prime pana la i. Cu asta ai rezolvat problema in O(n). Bad point: sursa cam mare (multi KB), s-ar putea sa n-o primeasca.


rezolvarea dn articol se refera la o preprcesare a vectorului inainte de a intra in ciclu de q teste, nu o preprocesare a intregului vector, folosind un alt program.


Titlul: Răspuns: 782 Densitate
Scris de: Florian Marcu din Decembrie 16, 2008, 20:54:58
Eu am facut problema generand intr-un vector numerele prime prin intermediul ciurului. Apoi am aplicat doua cautari binare in vectorul de numere prime, pt fiecare pereche (a,b). A intrat fara probleme.  :)


Titlul: Răspuns: 782 Densitate
Scris de: Catalin Ionescu din Decembrie 16, 2008, 23:22:37
ideea cea mai simpla dupa parerea mea e cea pe care am discutat-o la inceput... faci un vector de rezultate (int) in care pui nr de numere prime pana la nr curent... chiar daca numarul este compus
spre ex : i = 10
v[10] = 4
i= 11
v[11] = 5
e simplu :D si dupa calculezi cate numere sunt in interval :D ca daca faci doar ciur testele sunt date smecher.. te pune sa calculezi intre 1 si 11 si dupa 1 si 12.. 1 si 13.. si tot asa... si asa da TLE :) 


Titlul: Răspuns: 782 Densitate
Scris de: Florian Marcu din Decembrie 17, 2008, 11:36:45
ideea cea mai simpla dupa parerea mea e cea pe care am discutat-o la inceput... faci un vector de rezultate (int) in care pui nr de numere prime pana la nr curent... chiar daca numarul este compus
spre ex : i = 10
v[10] = 4
i= 11
v[11] = 5
e simplu :D si dupa calculezi cate numere sunt in interval :D ca daca faci doar ciur testele sunt date smecher.. te pune sa calculezi intre 1 si 11 si dupa 1 si 12.. 1 si 13.. si tot asa... si asa da TLE :) 

Nu ai inteles ce am spus. Eu nu fac ciur pt fiecare pereche de numere (a,b) ci fac ciur doar odata, la inceput, intre 1 si n. Iar intr-un vector retin numerele prime intre 1 si n. Acesta este vectorul pe care fac apoi cautarile binare.  :)


Titlul: Răspuns: 782 Densitate
Scris de: Flaviu Pepelea din Decembrie 17, 2008, 15:39:54
merge si fara cautari binare


Titlul: Răspuns: 782 Densitate
Scris de: Florian Marcu din Decembrie 17, 2008, 16:35:18
merge si fara cautari binare

Nu zice nimeni ca nu merge si fara. Eu doar am prezentat o alta metoda de rezolvare.  :thumbup:


Titlul: Răspuns: 782 Densitate
Scris de: gaboru corupt din Decembrie 17, 2008, 16:52:17
am si eu o intrebare...eu in concurs am facut o rezolvare mai putin ortodoxa si am preprocesat toate nr prime si leam bagat intr-un vector. ideea e ca sursa mea depaseae 256 de kb si nu ma lasa sa o trimit...bine, am mai scos din numere si pana la urma am scos 50 de puncte (TLE, nu am facut cautarea binara :P). va rog sa imi ziceti daka as putea "inghesui" toate numerele prime...care sunt aprox. 47 000 fara ca sursa mea sa depaseasca 256 kb....merci anticipat :)


Titlul: Răspuns: 782 Densitate
Scris de: Flaviu Pepelea din Decembrie 17, 2008, 17:30:01
dc nu ai calculat in acelasi program cu ciuru numerele prime.....ti s-a parut mai simplu sa bagi direct in sursa?


Titlul: Răspuns: 782 Densitate
Scris de: gaboru corupt din Decembrie 17, 2008, 17:35:58
pe moment am avut si ideea de ciur dar am zis ca incerc cu preprocesare ca sigur scot maxim...da nu o fost asa...ce sa zic...dupa concurs am rezolvat-o cu ciur si acum ma intreb daka merge si cu preprocesare


Titlul: Răspuns: 782 Densitate
Scris de: Emanuel Cinca din Decembrie 17, 2008, 17:48:37
sunt 41539 de nr prime... cel putin eu asa am gasit :P... probabil s-a gandit si la faptul ca va economisi un timp destul de mare, daca nu mai foloseste ciurul...


Titlul: Răspuns: 782 Densitate
Scris de: Andrei Misarca din Decembrie 17, 2008, 18:03:08
Avand in vedere ca N < 5 * 105, iar complexitatea ciurului e aproape O(N) (v. postul de pe blog), formarea ciurului nu mananca foarte mult timp


Titlul: Răspuns: 782 Densitate
Scris de: gaboru corupt din Decembrie 17, 2008, 18:09:14
am inteles ca ciurul e cea mai buna idee dar ce intreb eu e cu totul altceva... pot pune 41 si cate zice manu de nr prime in vector fara ca sursa mea sa depaseasca 256 de kbs?

P.S: am vazut ca ciurul nu manca mult timp ca pana la urma am luat 100 pe ea. dar cu preprocesare pot scoate 100?


Titlul: Răspuns: 782 Densitate
Scris de: Sima Cotizo din Decembrie 17, 2008, 18:40:38
Presupun ca faci un vector de constante. Ai putea incerca sa le scrii in hex (baza 16) pentru ca e posibil ca pentru unele numere sa folosesti mai putine caractere.

De asemenea poti incerca o codare in care fiecare numar sa il scrii ca pe un string, iar fiecare cifra sa o consideri un caracter intr-o baza aleasa de tine (100 de exemplu). Totusi, cred ca decodificarile ti-ar lua cam la fel ca ciurul...


Titlul: Răspuns: 782 Densitate
Scris de: Flaviu Pepelea din Decembrie 17, 2008, 18:46:11
baga ciuru pe biti...ca apoi nu te mai gandesti tu ca mananca timp (uita-te in arhiva educationala ca pt 2 000 000 intra in 16 ms):)).... incercati sa va descurcati si fara sa puneti un vector ca constanta.....nu arata grozav nici o sursa de 300 de kb.


Titlul: Răspuns: 782 Densitate
Scris de: gaboru corupt din Decembrie 17, 2008, 19:00:50
merci pt raspunsuri;) un + la voi :ok:


Titlul: Răspuns: 782 Densitate
Scris de: Robert Hangu din Decembrie 17, 2008, 23:25:42
merge foarte bine, dupa ciur, un arbore indexat binar sau unul de intervale pentru interogare


Titlul: Răspuns: 782 Densitate
Scris de: Gabriel Bitis din Decembrie 17, 2008, 23:31:48
De ce se prefera solutii asa complicate cand solutia oficiala e foarte simpla?  ??? ???


Titlul: Răspuns: 782 Densitate
Scris de: Robert Hangu din Decembrie 17, 2008, 23:43:29
nu m-am uitat peste solutiile oficiale. a fost prima varianta care mi-a venit in cap, am implementat-o si a mers. poate ajuta totusi pe cineva si o asemenea abordare.


Titlul: Răspuns: 782 Densitate
Scris de: Tirca Bogdan din Decembrie 29, 2008, 15:32:07
Intre 7 si 20 se refera la intervalu (7,20)(logic) sau [7,20](ilogic).
e logic sau ilogic?:))
Later: imi dadui seama ca e "ilogic" :D


Titlul: Răspuns: 782 Densitate
Scris de: Vlad Schnakovszki din Februarie 27, 2009, 21:38:36
Ce are mai special testul 3 ? Imi da wrong answer pe el ... Am incercat daca a=b, daca a e minim si b e maxim, daca a sau b sunt prime. Ce caz particular am putut uita ?


Titlul: Răspuns: 782 Densitate
Scris de: razyelx din Februarie 27, 2009, 23:01:50
Daca iti da WA pe testul 3 nu are cum sa fie de la limite. Cel mai sigur ca e la cautarea binara. Eu de exemplu nu am stiut sa fac cautarea binara foarte exacta, si dupa fiecare cautare verificam niste treburi. Dar zi cum ai facut tu.



Titlul: Răspuns: 782 Densitate
Scris de: Vlad Schnakovszki din Februarie 28, 2009, 07:50:08
Asta e cautarea binara :
Cod:
long cbin (long w, bool e)
{
   long x1, y1, mij;
   x1=1;
   y1=k;
   mij=(x1+y1)/2;
   while (x1<=y1)
    {
      if (s[mij]<=w&&s[mij+1]>w&&e)
      return mij;
      if (s[mij]>=w&&s[mij-1]<w&&!e)
      return mij;   //Aici nuintra cand mij=2.
      if (w<s[mij])
      y1=mij-1;
      else
      x1=mij+1;
      mij=(x1+y1)/2;
      }
   }

Iar asta e bucata cu tiparirea :
Cod:
for (i=1;i<=q;i++)
{
   if (i==3)
    i=3;
   fscanf(f, "%ld%ld", &x, &y);
   if (x<=2&&y>=s[k])
    {
      fprintf(g, "%ld\n", k);
      continue;
      }
   fprintf(g, "%ld\n", cbin(y, 1)-cbin(x, 0)+1);
   }


Titlul: Răspuns: 782 Densitate
Scris de: razyelx din Februarie 28, 2009, 08:31:43
Mda... si eu avut aceeasi problema cu 2 parca. Dar Prindeam mai cazuri nasoale, pentru ca cautarea binara incrementa ceva in plus.
Oricum trebuie sa modifici afisarea, cum am facut si eu de altfel:

Cod:
         i=bs(a,1);  
         j=bs(b,2); 
 
         if(a == prime[i] && b != prime[j]){ 
            fprintf(out,"%ld \n",j-i); 
          } 
 
 
           if(a != prime[i] && b == prime[j]){ 
            fprintf(out,"%ld \n",j-i+1); 
          } 
   
          if(a == prime[i] && b == prime[j]){ 
            fprintf(out,"%ld \n",j-i+1); 
          } 
 
          if(a != prime[i] && b != prime[j]){ 
            fprintf(out,"%ld \n",j-i); 
          }
Oricum te prinzi tu care e faza din afisare ca esti cuprins de problema, eu am mai uitat sustele. Daca iti iese imi dai un ceai la scoala.  :D


Titlul: Răspuns: 782 Densitate
Scris de: Vlad Schnakovszki din Februarie 28, 2009, 15:07:33
Nu e aia problema, ms oricum :(
Ideea e ca imi da bine pe orice test imi pot eu imagina... Se pare ca testul 2 e ceva caz particular ... Desi le-am incercat pe toate ... Alte idei ? :(


Titlul: Răspuns: 782 Densitate
Scris de: Emanuel Cinca din Februarie 28, 2009, 17:22:50
depinde de metoda ta...am vazut ca folosesti o cautare binara... descrie putin ce faci acolo... ce cauti binar? eu am rezolvat fara cautare binara, doar un ciur :)


Titlul: Răspuns: 782 Densitate
Scris de: razyelx din Februarie 28, 2009, 18:11:20
frate... problema e la afisare. Pentru i-uri diferite, ai acelasi numar de numere prime. Acolo intervine omica problema la cautarea binara. Stiu ca mi-e nu imi dadea bine la unmoment dat nici pe exemplu pt b=19 sau b=20. La 19 cand se modfica(de la 18 se trece la 19 se mareste numarul de nr prime) nu iti returneaza ce vrei ca nu mai icnrementeaza, iar la 20 se va opri la 19. Ceva de genu era. bafta! daca nu iti iese. iti postez cautarea mea binara.


Titlul: Răspuns: 782 Densitate
Scris de: Vlad Schnakovszki din Martie 01, 2009, 22:49:01
Seba eu tot am incercat sa fac cum zici tu dar tot aia da. Deci am stat cu Manu C. 2 zile sa vedem ce are si pauza... Postez acum toata sursa (sper ca e ok) ca deja am facut gauri in tastatura.
Cod:
#include <stdio.h>
FILE *f, *g;
long k=0, s[45550], i, j, n, q, x, y, t;
bool v[500005];

long cbin (long w, bool e)
{
   long x1, y1, mij;
   x1=1;
   y1=k;
   mij=(x1+y1)/2;
   while (x1<=y1)
    {
      if (s[mij]<=w&&s[mij+1]>w&&e)
      return mij;
      if (s[mij]>=w&&s[mij-1]<w&&!e)
      return mij; 
      if (w<s[mij])
      y1=mij-1;
      else
      x1=mij+1;
      mij=(x1+y1)/2;
      }
   return mij;
   }

void ciur(void)
{
   s[1]=2;
   k=1;
   for (i=3;i<=n;i+=2)
    if (!v[i])
      {
         s[++k]=i;
         if (i<=707)
      for (j=i;i*j<=n;j++)
          v[i*j]=1;
         }
   }

int main(void)
{
f=fopen("densitate.in", "r");
g=fopen("densitate.out", "w");
fscanf(f, "%ld%ld", &n, &q);
ciur();

for (i=1;i<=q;i++)
{
   if (i==3)
    i=3;
   fscanf(f, "%ld%ld", &x, &y);
   if (x<=2&&y>=s[k])
    {
      fprintf(g, "%ld\n", k);
      continue;
      }   
   fprintf(g, "%ld\n", cbin(y, 1)-cbin(x, 0)+1);
   }
fcloseall();
return 0;
}



Culmea e ca pe sursa asta iau testu 2 dar e prea inceata :|
Cod:
#include <stdio.h>
#include <math.h>
FILE *f, *g;
long k=0, s[41550], i, j, n, q, x, y, t;
bool v[500001];

void ciur(void)
{
   s[1]=2;
   k=1;
   for (i=3;i<=n;i+=2)
    if (!v[i])
      {
         s[++k]=i;
         if (i<=707)
      for (j=i;i*j<=n;j++)
          v[i*j]=1;
         }
   }

int main(void)
{
f=fopen("densitate.in", "r");
g=fopen("densitate.out", "w");
fscanf(f, "%ld%ld", &n, &q);
ciur();
for (i=1;i<=q;i++)
{
   fscanf(f, "%ld%ld", &x, &y);
   for (j=1;j<=k;j++)
    if (s[j]>=x)
      break;
   t=j;
   for (;j<=k;j++)
    if (s[j]>y)
      break;
   fprintf(g, "%ld\n", j-t);
   }
fcloseall();
return 0;
}

Cineva ceva idei ?  ](*,)


Titlul: Răspuns: 782 Densitate
Scris de: Popescu Marius din Martie 01, 2009, 23:48:13
  Cred ca s-a mai spuns in posturile anterioare , dar iti mai spun si eu , ca sa iti intre in timp poti sa faci cu Ciurul lui Eratostene si fara cautare binara , iti ti un vector x [ i ] ( 1<=i<=n) in care pe pozitia x [ i ] iti reti cate numere prime exista de la 1 la i , iar pentru fiecare intrebare de genu :"cate numere prime sunt in intervalul a b " tu afisezi  x[ b ]-x[ a ]
    Vad ca sti sa faci ciurul lui eratostene  asa ca tot ce tre sa faci ca sa iei 100 e sa stergi cautarea binara si sa modifici un pic ciurul la ceva de genu :
Cod:

void ciur()
{
    x[1]=0;nr=1;
    for(int i=2;i<=N;i++)
      if(!fol[i])
       {
        x[++nr]=x[nr-1]+1;
        for(int k=2;k*i<=N;k++)
          fol[k*i]=1;
       }
       else x[++nr]=x[nr-1];

}

Sper ca te-am ajutat .


Titlul: Răspuns: 782 Densitate
Scris de: Emanuel Cinca din Martie 01, 2009, 23:58:38
Citat
Cred ca s-a mai spuns in posturile anterioare , dar iti mai spun si eu , ca sa iti intre in timp poti sa faci cu Ciurul lui Eratostene si fara cautare binara , iti ti un vector x [ i ] ( 1<=i<=n) in care pe pozitia x [ i ] iti reti cate numere prime exista de la 1 la i , iar pentru fiecare intrebare de genu :"cate numere prime sunt in intervalul a b " tu afisezi  x[ b ]-x[ a ]
    Vad ca sti sa faci ciurul lui eratostene  asa ca tot ce tre sa faci ca sa iei 100 e sa stergi cautarea binara si sa modifici un pic ciurul la ceva de genu :...

vlad a intrebat daca stie cineva care e problema la varianta lui... nu a cerut alta varianta... se intra in timp si folosind cautare binara... doar ca mai trebuie slefuita putin ca primeste un WA pe care nu a reusit sa il corecteze... probabil e ceva caz particular ce nu-l prinde... eu nu l-am gasit... poate il stie altcineva ce a folosit varianta asta...

PS: nu inteleg de ce in momentul in care se incearca alta varianta de rezolvare veniti toti si repetati solutia oficiala de la problema??!!


Titlul: Răspuns: 782 Densitate
Scris de: gaboru corupt din Martie 01, 2009, 23:59:24
defapt pt metoda aia trebuie sa afisezi x[ b ] - x[ a -1 ] ca poate pe pozitia a ai un numar prim. + ca am aceasi parere ca a lui manu;)


Titlul: Răspuns: 782 Densitate
Scris de: razyelx din Martie 02, 2009, 00:27:13
daca el vrea sa faca binar,lasa-ti-le sa faca binar.
deci Vlad ti-am zis cautarea ta nu poate fi exacta. Deci tu ai vecotrul 2 3 5 7 11 13 17 19.... Iar daca ai a=2 b = 19. Cate numere prime ai? In cazul asta rezolvarea ta va tiparii 8. La a = 4 si b = 19 va tiparii 7, adik corect. Dar daca ai a=2 si b=18 programul tau va afisa 8, corect fiind 7. Iar pt a=4, b = 18 programul tau va afisa 6, corect fiind 5.

uite cautarea mea binara:
Cod:
 long bs(long x){  
      long s=1,d = h,m,i; 
      while(s+2<d){ 
     m = (s+d)/2; 
     if(x == prime[m]) return m; 
   
     if(x>prime[m])s = m+1; 
     else d = m-1; 
      } 
      i=s; 
      while(x>prime[i] && i<=d)i++; 
      return i; 

prime[] e vectorul tau s[]. Am lasat ca marginea inferioara sa fie mai mica cu 3 decat cea superiaora ca sa pot cauta secvential exact nr care ma intereseaza pentru ca imi sarea. Nu pot explica foarte exact pt ca am rezolvat-o anul trecut.

iar afisarea:
Cod:
  if(a == prime[i] && b != prime[j]){  
             fprintf(out,"%ld \n",j-i); 
           } 
   
   
           if(a != prime[i] && b == prime[j]){ 
             fprintf(out,"%ld \n",j-i+1); 
           } 
   
           if(a == prime[i] && b == prime[j]){ 
             fprintf(out,"%ld \n",j-i+1); 
           } 
   
           if(a != prime[i] && b != prime[j]){ 
             fprintf(out,"%ld \n",j-i); 
           } 
sper ca te-am ajutat. Apropo pe testul initial de pe infoarena iti merge?


Titlul: Răspuns: 782 Densitate
Scris de: Vlad Schnakovszki din Martie 03, 2009, 09:35:41
Nu va luati de om daca vrea sa ajute  :peacefingers:
Seba iti multumesc ca vrei sa ma ajuti dar pe toate exemplele tale imi dau bine rezultatele...
O sa incerc si metoda fara binara cand ajung acasa dar ar fi dragut sa o corectam si pe cea cu binara pentru ca pe orice exemplu am intalnit pana acum imi da bine ...
Thanks guys  :D


Titlul: Răspuns: 782 Densitate
Scris de: gaboru corupt din Martie 03, 2009, 09:51:50
incearca sa cauti binar pe A, respectiv B, iar daka nu il gasesti returneazati pozitia stanga (limita stanga a intervalului in care il cauti). si atunci verifici daca pe pozitia returnata de cautarea binara ai numar prim sau nu. din cate am observat, te-ai cam complicat acolo.

Cod:
binary(int elem_cautat)
{
start = 1;
finish = k;
while(start <= finish)
{
    middle = (start+finish)/2;
    if( elem_cautat == a[middle])
         return middle
    else
        if(elem_cautat < a[middle])
                  finish = middle -1;
        else
                  start = middle+1;
}
return start;
}


si dupa ai cele 4 conditii pe care le-a postat si sebi mai sus.


Titlul: Răspuns: 782 Densitate
Scris de: Vlad Schnakovszki din Martie 03, 2009, 12:03:41
Am facut de 100 cu solutia lui jupanubv92 :yahoo:
Desi ar fi frumos sa aflu ce era gresit la cautarea binara .... ???


Titlul: Răspuns: 782 Densitate
Scris de: Nicoara Ionut din Martie 18, 2009, 10:16:16
de ce nu merge?!? cred ca-i problema fisierului de intrare si de iesire  :-k :-k :-k


Titlul: Răspuns: 782 Densitate
Scris de: Florian Marcu din Martie 18, 2009, 11:11:38
de ce nu merge?!? cred ca-i problema fisierului de intrare si de iesire  :-k :-k :-k

Problema este de fapt a ta. Nu a fisierelor de intrare/iesire. Spune cum faci si ce erori iti da.


Titlul: Răspuns: 782 Densitate
Scris de: Andrici Cezar din Martie 21, 2009, 07:57:11
Cum ati facut voi cu un ciur ](*,)? Eu am facut cu o baza de numere prime si am luat 50 pct, iar cu ciuru i-au doar 40. Am un test la care zice ca iese din timp si la celelalte nu am suficienta memori... Ajutatima macr sa o fac pe aia cu baza de numere prime ca acolo doar ies din tim.  :readthis: :-s

P.S. am trimis de doua ori aceeasi sursa si o data am luat 40 si o data 50... Ar fi trebuit? :-'


Titlul: Răspuns: 782 Densitate
Scris de: UPB-Hulea-Ionescu-Roman din Aprilie 01, 2009, 23:48:48
problema se poate rezolva foarte usor cu ciurul... ordinea de idei este urmatoarea:

-ciurul pe 500.000 numere;
-calculezi intr-un vector "v" cate valori prime ai pana la numarul i<=n;
-citesti din fisierul de intrare testele, pe rand si afisezi v[prima val citita]-v[a 2-a val citita];

sper sa va ajute  :wink:


Titlul: Răspuns: 782 Densitate
Scris de: Cotirlea Anamaria din Aprilie 25, 2009, 12:24:32
Am rezolvat si eu problema folosind ciurul dar imi iese din timp la ultimul test. Ce optimizari as putea sa fac ca sa iau 100?   :-k


Titlul: Răspuns: 782 Densitate
Scris de: Rusu Radu din Mai 27, 2009, 20:14:19
Intrebare: Trimit o sursa la aceasta problema si uraaaaaaaaaaaaa 100 de pct, trimit aceeasi sura peste 10 minute is bau 90 de pct (TLE la ultimu test)... nu vi se pare suspect.... lamuritzima:D


Titlul: Răspuns: 782 Densitate
Scris de: Marius Stroe din Mai 27, 2009, 21:04:46
Intrebare: Trimit o sursa la aceasta problema si uraaaaaaaaaaaaa 100 de pct, trimit aceeasi sura peste 10 minute is bau 90 de pct (TLE la ultimu test)... nu vi se pare suspect.... lamuritzima:D

Ultimul test îţi intră în timp la limită. Dacă mai optimizezi puţin programul vei lua 100 tot timpul. ;)


Titlul: Răspuns: 782 Densitate
Scris de: A Cosmina - vechi din Iulie 25, 2009, 22:38:44
Am citit topicul si am gasit multe idei bune aici. Am decis sa fac astfel: cu un ciur aflu cate numere prime sunt de la 1 pana la N, apoi intr-un vector x trebuie sa am ceva d egenul x[ i ]= cate numere prime sunt de la 1 pana la N. Adica sa fac un ciur( i ).

Ciurul arata asa:

Cod:
long ciur(long n)
{
     int i,j;
     for (i=2;i<=n;i++)
         prim[i]=1;
     for (i=2;i<=n;i++)
         if (prim[i])
          {
          nr++;
          for (j=i+i;j<=n;j+=i)
              prim[j]=0;
          }
     return nr;
}

Iar functia o apelez astfel: 
Cod:
for (i=1;i<=N;i++)
        x[i]=ciur(i);


Problema este ca numerele din x nu sunt cele necesare, unde gresesc ?  :sad:


Titlul: Răspuns: 782 Densitate
Scris de: Sima Cotizo din Iulie 25, 2009, 22:43:15
Reinitializezi nr la 0 din cand in cand? :)

Oricum, (nu mai stiu rezolvarea problemei, dar...) de ce apelezi ciur de N ori? Poti sa-l faci o data (apelezi ciur(N)) si, daca tot ai un for de la 1 la N, sa numeri cate numere prime ai intalnit pana la un moment dat.


Titlul: Răspuns: 782 Densitate
Scris de: A Cosmina - vechi din Iulie 25, 2009, 23:30:10
Pai apelez la ciur de n ori pentru a calcula cate nr prime am de la 1 la i . Ciurul imi returneaza cate numere prime am de la 1 pana la ce numar vreau eu, in cazul meu i.

N-am priceput exact ce ai vrut sa zici, as putea posta cod sa ne lamurim mai repede. Daca am permisiunea ... (stiu ca nu prea se da voie). Thanks for the answer ! :)

Edit: Aaaa,cred ca m-am prins ! Ar trebui mai degraba sa retin in vector ce valori prime am pana la n si apoi sa afisez x[a]-x[ b ]. Asa ?  :shock:


Titlul: Răspuns: 782 Densitate
Scris de: Popescu Marius din Iulie 26, 2009, 18:37:22
    Rezolva mai intai problema de la arhiva educationala cu ciuru si o sa iti dai seama cum sa modifici ciuru ca sa nu fi nevoita sa il apelezi de n ori .
    Dupa ce ti-ai construit vectoru ala ca in mesaju care mi l-ai trimis , dar de data asta eficient , trebuie sa afisezi x[ b ]-x[ a-1 ] ci nu x[ a ]-x[ b ] .
    Sper ca te-am ajutat alta data incearca sa studiezi mai mult mesajele precedente de pe forum pentru ca s-au dat foarte multe indicatii de rezolvare la problema asta .

LE: Se pare ca pe pagina a doua am postat codu pentru ciur , mai trebuie doar sa afisezi x[ b ]-x[ a-1 ].
LEE: Sursa trimisa de tine prin PM nu este completa si nu se vede toata iar din cauza asta nu am putut sa vad cum ai facut tu ciuru.


Titlul: Răspuns: 782 Densitate
Scris de: Sima Cotizo din Iulie 26, 2009, 18:59:12
Pai apelez la ciur de n ori pentru a calcula cate nr prime am de la 1 la i . Ciurul imi returneaza cate numere prime am de la 1 pana la ce numar vreau eu, in cazul meu i.

N-am priceput exact ce ai vrut sa zici, as putea posta cod sa ne lamurim mai repede. Daca am permisiunea ... (stiu ca nu prea se da voie). Thanks for the answer ! :)

Pana sa rezolvi problema optim, sa iti zic de ce, in parerea mea, nu functioneaza codul. Tu ai ceva care arata asa:

Cod:
long ciur(long n)
{
     int i,j;
     for (i=2;i<=n;i++)
         prim[i]=1;
     for (i=2;i<=n;i++)
         if (prim[i])
          {
          nr++;
          for (j=i+i;j<=n;j+=i)
              prim[j]=0;
          }
     return nr;
}

Iar functia o apelez astfel: 
Cod:
for (i=1;i<=N;i++)
        x[i]=ciur(i);


In functia ciur, eu nu prea vad variabila "nr" reinitializata la 0. Cred ca pe masura ce apelezi ciur, valorile x[ i ] sunt din ce in ce mai mari (strict crescator)... asta e de la reinitializarea uitata :) Incearca asa:

Cod:
long ciur(long n)
{
     int i,j;
     nr = 0;                    // ! atentie aici
     for (i=2;i<=n;i++)
         prim[i]=1;
[... etc]
     return nr;
}

Sper ca nu gresesc si ca nu e altundeva problema.


Titlul: Răspuns: 782 Densitate
Scris de: A Cosmina - vechi din Iulie 26, 2009, 19:56:14
Am creat alt ciur. In x pun nr prime de la 1 la N. Apoi afisez x[ b ]-x[ a-1].
Ciurul este:

Cod:
for(int i=2;i<=N;i++) 
          x[i]=1;
  for(int i=2;i*i<=N;i++)
    if(x[i]==1) for(int j=2;j*i<=N;j++) x[i*j]=0;
  for(int i=2;i<=N;i++)
            if(x[i]==1) cout<<i<<' ';

Are si afisare. Nu pricep de ce nu imi arata bine afisarea finala,ceea ce trebuie sa obtin. Fac asa:

Cod:
 for (j=1;j<=Q;j++)
      {
      f>>a>>b;
      cout<<x[b]-x[a-1]<<endl;
      }

Daca am pus prea mult cod, sterg dupa. Mersi pentru ajutor.


Titlul: Răspuns: 782 Densitate
Scris de: Popescu Marius din Iulie 26, 2009, 20:23:00
Se pare ca nu prea ai inteles ce vrea problema de la tine . In primul rand n-ai cum sa afisezi x[ b ] - x[ a-1 ] cand tu in x ai valori de 0 si 1 . Din codul care l-ai postat eu inteleg ca tu pe x[ i ] retii 1 daca i este numar prim si 0 daca nu . In al doilea rand ca sa potzi sa afisezi x[ b ] - x[ a-1 ] trebuie ca pe pozitia x[ i ] sa fie numarul de numere prime din intervalul 1..i . Incearca sa intelegi ce vrea problema de exemplu daca tu stii cate numere prime exista de la 1 la a si de la 1 la b ca sa afli cate numere prime sunt intre a si b (b>=a) tot ce tre sa faci este sa afisezi  diferenta dintre numarul de numere prime al extremitatilor (a,b) .
    Mai concret daca in vectorul x reti numarul de numere prime pana la i (1..i..n) vectorul o sa arate asa : x[1]=0 x[2]=1 x[3]=2 x[4]=2 x[5]=3 x[6]=3 x[7]=4 x[8]=4 x[9]=4 x[10]=4 ....., iar daca iti cere sa afisezi cate numere prime sunt intre 1 si 10 afisezi x[10]-x[0] = 4 daca iti cere intre 3 si 7 afisezi x[7]-x[2] = 3 (daca de la 1 la 2 exista un numar prim , iar de la 1 la 7 exista 4 numere prime e logic ca intre 3 si 7 vor fi 3 ) .
    Sper ca ai inteles ..
   



Titlul: Răspuns: 782 Densitate
Scris de: A Cosmina - vechi din Iulie 26, 2009, 20:29:50
Am prins ideea, dar nu-mi dau seama cum sa fac sa bag in x nr de nr prime de la 1 pana la i . Trebuie sa apelez cirul de N ori si mai trebuie sa fac si alt ciur. Incerc cum mi-a spus cotizo.


Titlul: Răspuns: 782 Densitate
Scris de: Popescu Marius din Iulie 26, 2009, 20:34:34
Incearca cum a spus cotizo , dar nu stiu daca o sa intre in timp . Dupa ce faci asa poti sa te uiti la posturile anterioare de la problema si o sa vezi cum potzi sa faci si fara sa apelezi de n ori.


Titlul: Răspuns: 782 Densitate
Scris de: A Cosmina - vechi din Iulie 26, 2009, 20:51:26
Ce am incercat cu ciurul lui cotizo:

Cod:
nr=ciur(N);
    cout<<"nr="<<nr;
    for (i=1;i<=nr;i++)
        x[i]=ciur(i);

Imi da bine cate numere sunt intre 1 si N, dar nu se intampla nimic cu x[ i ].
Ma gandesc sa incerc altfel: intr-un vector v pun numerele prime de la 1 la N, vectorul asta va avea dimens nr. Si ca sa aflu x[ i ] iau i la la 1 la N si verific daca i==v[ j ], daca este egal il numar si dupa ce termin de numarat, bag ce am obtinut in x [ i ].

Nu cred insa ca intra in timp. Se poate mai simplu ?  :-k


Titlul: Răspuns: 782 Densitate
Scris de: Popescu Marius din Iulie 26, 2009, 20:59:07
 :) Pai nu ai incercat bine . Tu lui nr ii dai la inceput ciur(N) iar nr va fi numarul de nr prime din intervalul [1,N] iar cand iti construiesti vectorul x tu mergi pana la nr si de aia nu se intampla nimic cu x[ i ] , daca o sa faci for-ul pana la N x[ i ] o sa fie bun .

PS : daca vrei sa faci mai simplu uitete la paginile anterioare si o sa vezi ca am postat varianta de ciur cea mai simpla , e buna si solutia care vrei sa o faci dar probabil vrei obtine 50% din punctaj.

LE : offtopic incearca sa nu mai postezi asa de des pe forum la fiecare problema pe care o rezolvi am vazut ca ai vreo 10 probleme facute si 227 de mesaje , la unele probleme daca nu reusesti sa le dai de cap potzi gasi rezolvarea doar citind cateva mesaje de pe forum . Este doar un sfat asa faceam si eu pe la inceput si au auzit impresia mai multor oameni ,care imi tot raspundeau la mesaje ,acum dupa vreo 2 ani si credema se saturase de mine .


Titlul: Răspuns: 782 Densitate
Scris de: Sima Cotizo din Iulie 26, 2009, 21:06:55
Ptr N-uri acceptabil de mari eu as face sa pun in X[ i ] "numarul de nr prime mai mici ca i" ceva de genul:
Cod:
long ciur(long n) {
int i,j;
nr = 0;
for (i=2;i<=n;i++)
este_prim[i]=1;
for (i=2;i<=n;i++) {
if (este_prim[i]==1) {
nr++;
for (j=i+i;j<=n;j+=i)
este_prim[j]=0;
}
X[i] = nr;
}
return nr;
}

Apelezi o singura data functia ciur(N) si ai vectorul X[ i ] gata. Complexitatea este O(N^2) (sau p-acolo :P). Bineinteles, am folosit o varianta de ciur mult simplificata, pe aceeasi idee poti sa mergi cu un ciur mai "complicat" (citeste articolul asta (http://infoarena.ro/ciurul-lui-eratostene)).

Cred ca repet, dar: nu am citit problema si nu m-am gandit cum as rezolva-o de fapt, dar incerc sa-ti dau indicatii pe ideea ta. Poti sa fii si tu creativa si sa incerci diverse combinatii intre ciurul din articol si o cautare binara pentru a determina cate nr prime sunt mai mici ca i ( hint : tii un vector de numere prime ;) )


Titlul: Răspuns: 782 Densitate
Scris de: A Cosmina - vechi din Iulie 26, 2009, 21:15:55
Am reusit sa scot 30 de puncte pe ea. Multumesc pt raspunsuri jupanului si lui cotizo. O sa ma mai chinui la ea o vreme, o sa gandesc singura. Doar daca ma impiedic tare mai intreb de ea.

O sa incerc si cu ciurul nou, poate si cautare binara. Thanks a lot.  :thumbup:


Titlul: Răspuns: 782 Densitate
Scris de: Emilian Paraicu din Iulie 28, 2009, 10:33:03
Iau Killed by Signal la ultimele 5 teste, si sunt destul de sigur ca nu sunt probleme de memorie, stie cineva de ce?:D
Later Edit: Se pare ca aveam probleme cu memoria, ciurul meu genera numere prea mari(nu pusesem i*i<=n ci doar i), acum am luat 100pct:).


Titlul: Răspuns: 782 Densitate
Scris de: Alexandru-Iancu Caragicu din Octombrie 24, 2009, 17:42:33
Eu fac cu totul altfel.
Eu imi pun numerele prime intr-un vector folosind un ciur (unul dupa altul) si apoi caut binar in vector numerele, scazand indicii la care ii gasesc.  :winner1:

___________________________________Mai tarziu________________________________________________

Am facut si cu metoda populara...

O mica greseala in textul problemei: a, b < N in cerinta, a ≤ b ≤ N la restrictii.


Titlul: Răspuns: 782 Densitate
Scris de: Nicolaescu Horia din Martie 12, 2010, 12:49:50
cum se poate sa iau cu exact aceeasi sursa 80 si peste un minut 90?


Titlul: Răspuns: 782 Densitate
Scris de: Andrei Grigorean din Martie 12, 2010, 12:52:21
Sursa ta este chiar la limita si astfel poti obtine punctaje diferite la rulari succesive.


Titlul: Răspuns: 782 Densitate
Scris de: Aiordachioaei Marius din Aprilie 15, 2012, 21:44:33
daca fac citire/afisare cu streamuri imi intra in timp la toate dar daca fac citire standard imi da TLE pe ultimul


Titlul: Răspuns: 782 Densitate
Scris de: Ionescu Iulian din Noiembrie 12, 2015, 12:51:18
Salut, am facut si eu codul folosind o functie cu ciurul pe cele N numere, schimband insa for( k=2;k*i<=N;k++) cu  for( k=i;k*i<=N;k++) ca sa nu mai am situatiile de genul 2*3 apoi 3*2, insa iau decat 30 de puncte. Daca pun for-ul de la k=2 iau 30 , restul TLE, iar daca pun for-ul de la k=i iau 30 si de la testul 5 in colo Killed by signal 11. aveti vreo idee cum sa reduc timp sau sa fac anumite imbunatatiri ? *vectorul de sume cumulate si cel de marcare cu 1 si 0  sunt definiti pana la 500001*