Pagini recente » Cod sursa (job #1192613) | Cod sursa (job #647231) | Cod sursa (job #942447) | Cod sursa (job #1105255) | Cod sursa (job #2376941)
/**
* Folosim Ciurul lui Eratostene pentru a obține toate numerele prime până la N,
* după care le numărăm și afișăm rezultatul.
*
* O implementare eficientă a ciurului se poate găsi în acest articol:
* https://infoarena.ro/ciurul-lui-eratostene
*/
#include <bits/stdc++.h>
using namespace std;
const int NMAX = 1000001;
bool sieved[NMAX];
// Marcheză numerele compuse până la n folosind Ciurul lui Eratostene, astfel
// încât doar numerele prime mai mici ca n vor fi nemarcate.
void compute_sieve(int n) {
/**
* Parcurgem numerele de la 1 la sqrt(n), ignorându-le pe cele pare, deoarece
* știm că doar 2 este par și prim. În acest caz, sieved[i] = false înseamnă
* că numărul 2*i + 1 nu a fost „cernut”, adică este prim.
*
* Ne oprim când 2*i + 1 = sqrt(n). Acestui număr îi corespunde un indice x,
* astfel încât:
* 2x + 1 = (2*i + 1)^2 <=>
* x = 2*i^2 + 2*i,
* de unde condiția for loop-ului exterior, cât și valoarea inițială a lui j
* în for loop-ul interior.
*/
for (int i = 1; ((i * i) << 1) + (i << 1) <= n; ++i) {
if (!sieved[i]) {
for (int j = ((i * i) << 1) + (i << 1); (j << 1) + 1 <= n;
j += (i << 1) + 1) {
sieved[j] = true;
}
}
}
}
int main() {
stdin = freopen("ciur.in", "r", stdin);
stdout = freopen("ciur.out", "w", stdout);
int N;
cin >> N;
compute_sieve(N);
int primes_found = 0;
for (int i = 0; i < N / 2; ++i) {
if (!sieved[i]) {
primes_found++;
}
}
cout << primes_found;
}