Pagini recente » Cod sursa (job #50298) | Cod sursa (job #3032494) | Cod sursa (job #444756) | Cod sursa (job #1251822) | Cod sursa (job #2341634)
#include <stdio.h>
#include <stdlib.h>
typedef unsigned char *set;
// Prezenta bitului i in set marcheaza faptul ca 2 * i + 1 este prim
// 0 inseamna ca valoarea este in set, in timp ce 1 marcheaza lipsa
void remove_from_set(set s, int val) {
int byte = (val >> 3), bit = (val & 7);
s[byte] |= (1 << bit);
}
int is_in_set(set s, int val) {
int byte = (val >> 3), bit = (val & 7);
if (s[byte] & (1 << bit)) {
return 0;
}
return 1;
}
set declare_set(int n) {
set s = calloc((n + 15) / 16, sizeof(char));
if (s == NULL) {
printf("Nu s-a putut aloca memorie\n");
return NULL;
}
return s;
}
void print_set(set s, int n, FILE* out) {
for (int i = 0 ; i <= n / 2 - 1 ; ++i) {
if (is_in_set(s, i)) {
fprintf(out, "%d ", 2 * i + 1);
}
}
if (n & 1) {
fprintf(out, "%d\n", n);
}
}
int counter(set s, int n) {
int i, ct = 1;
for (i = 3 ; i <= n ; i += 2) {
if (is_in_set(s, i / 2)) {
ct++;
}
}
return ct;
}
// Contorul incepe de la 1, marcand prezenta lui 2 in set
void ciur(set s, int n) {
int i, j;
for (i = 1 ; ((i * i) << 1) + (i << 1) <= n ; ++i) {
if (is_in_set(s, i)) {
for (j = ((i * i) << 1) + (i << 1); (j << 1) + 1 <= n ; j += (i << 1) + 1) {
remove_from_set(s, j);
}
}
}
}
int main() {
FILE *in, *out;
if (((in = fopen("ciur.in", "rt")) == NULL)) {
printf("Nu am putut deschide fisierul de input!");
return -1;
}
if (((out = fopen("ciur.out", "wt")) == NULL)) {
printf("Nu am putut deschide fisierul de output!");
return -2;
}
int n;
fscanf(in, "%d", &n);
set s = declare_set(n);
ciur(s, n);
int result = counter(s, n);
fprintf(out, "%d\n", result);
// Freeing the memory
free(s);
fclose(in);
fclose(out);
return 0;
}