Cod sursa(job #974565)

Utilizator Impaler_009Mihai Nitu Impaler_009 Data 17 iulie 2013 15:46:15
Problema Ciurul lui Eratosthenes Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.21 kb
#include <fstream>
#include <bitset>
using namespace std;
ifstream fin("ciur.in");
ofstream fout("ciur.out");

bitset <2000001> composite;
int nr,n,i,x;

/*Optimizari:
  1) Iteram doar prin elemente impare; toate numerele pare cu exeptia lui 2 sunt compuse
  2) Cand marcam numere compuse, pornind de la un numar prim i, incepem de la i*i; Toate numerele compuse de mai mici de i*i sunt de forma j*i. Toti multiplii de j au fost marcati anterior oricare ar fi j<i
  3) Din optimizarea anterioara reiese ca o data ce am ajuns la un numar prim i > sqrt(n), nu mai are sens sa incercam sa gasim numere compuse nemarcate, deoarece se va incepe de la i*i>sqrt(n)*sqrt(n)=n. Pentru a salva timp, restul algoritmului se va petrece intr-un for separat doar cu numarare de numere nemarcate
  *) Se mai poate injumtati memoria pentru ca nu folosim numerele pare si se mai poate optimiza efectuand operatiile pe biti dar va rezulta un cod greu lizibil
*/

int main()
{
    fin>>n;
    nr=1;   // Numarul 2 este prim

    for (i=3;i*i<=n;i+=2)
    {
        if (composite[i]) continue;
        nr++;
        for (x=i*i;x<=n;x+=i) composite[x]=1;
    }

    for (;i<=n; i+=2)
        if (!composite[i]) nr++;
    fout<<nr;
}