Cod sursa(job #1626239)

Utilizator emil_sirbuEmil Sirbu emil_sirbu Data 2 martie 2016 23:47:49
Problema Ciurul lui Eratosthenes Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.51 kb
#include <iostream>
#include <fstream>
#include <bitset>
using namespace std;

ifstream fin ("ciur.in");
ofstream fout ("ciur.out");

//problema spune ca N <= 2.000.000
//in "ciur" vom tine doar numerele impare, incepand cu 3
//(cele pare, mai putin 2, nu-s prime)
//deci avem nevoie de un ciur de dimensiune 2.000.000/2 -2
//ciurul (marked) va contine flag 0/1 pentru

//3 5 9 11 13 ...
//deci marked[i] ne va zice starea pentru 2*(i+1) + 1
//si. invers, pentru un numar N, vom gasi starea in marked[k-1], N=2k+1 

const int NMAX = 1000000; //sau 1<<20 daca vrem sa radem de Ionut
 
bitset < NMAX > marked; 

//alternativ putem folosi char marked[N/8]
// si, in loc de marked[i] = 1, folosim ceva gen marked | (1 << i)
// iar in loc de marked[i] == 1, folosim marked & (1<<i)

int main(){
 
	int N,prime=1; //asta e 2
	
    fin >> N;
   
	
    for(int i=3 ; i<=N ; i+=2) {
		
		//starea (prim = 1; neprim = 0) pt. nr. i (descompus ca 2k+1) 
		//este in marked[k-1]  
        if (!marked[(i-1)/2-1] ){  		
            prime++;
            
            //marcam toate numerele ce nu au cum sa mai fie prime 
            //algoritmul zice sa marcam de la 2*i, din i in i
            //pt. 3, marcam 6,9,12, 15 etc.
            // dar, noi nu avem in ciur numerele pare, 
            //deci o sa incepem de la 3*i 
            //si vom avansa cu 2*i  
            //pt. 3, marcam 9, 15 etc.
            for(int j = 3*i; j <= N; j += 2*i ) {
                marked[(j-1)/2-1] = 1;
			}
        }
    }
 
   
    fout << prime << "\n";
 
    return 0;
}