Cod sursa(job #67067)

Utilizator scvalexAlexandru Scvortov scvalex Data 22 iunie 2007 13:56:11
Problema Fractii Scor 10
Compilator c Status done
Runda Arhiva de probleme Marime 2.12 kb
#include <stdio.h>
#include <string.h>

int prime[78498];

int nrPrime = 0;

int citeste() {
  FILE *fin = fopen("fractii.in", "r");

  int n; 
  fscanf(fin, "%d", &n);

  fclose(fin);

  return n;
}

void genPrime(int n) {
  char p[1000001];

  memset(p, 1, sizeof(char) * (n + 1));

  p[1] = 0;
//   printf("{2");

  int i = 2;
  for (; i <= n; ++i)
    if (p[i]) {
//       printf(", %d", i);
      prime[nrPrime] = i;
      ++nrPrime;
      int j = i * 2;
      while (j <= n) {
        p[j] = 0;
        j += i;
      }
    }
//   printf("}\n");
//   printf("Total: %d numere prime\n", nrPrime);
}

int phi(int n) {
  double rez = n;

//   printf("Calculeaz phi(%d)...\n", n);

  int i = 0;
  while ((i < nrPrime) && (prime[i] <= n)) {
//     printf("Verific daca este divizibil cu %d\n", prime[i]);
    if (n % prime[i] == 0) {
      rez *= (double)(prime[i] - 1) / (double)prime[i];
//       printf("%g\n", (double)(prime[i] - 1) / (double)prime[i]);
    }
    ++i;
  }

  return rez;
}

void scrie(double rez) {
  FILE *fout = fopen("fractii.out", "w");

  fprintf(fout, "%.0f\n", rez);
//   printf("%.0f\n", rez);

  fclose(fout);
}

char relativPrime(int a, int b) {
//   printf("Intru in relativPrime(int, int)\n");
  int r;
//   printf("%d %d\n", a, b);
  while (b) {
    r = a % b;
    a = b;
    b = r;
//     printf("%d %d %d\n", a, b, r);
  }
//   printf("Ies din relativPrime(int, int)\n");
  return a == 1;
}

int main(int argc, char *argv[]) {
  int n = citeste();

  genPrime(n);

  float dejaCalculat[1000001];
  int i = 2;
  for (; i <= n; ++i)
    dejaCalculat[i] = 0;
  i = 2;
  float rez = 1;
  for (; i <= n; ++i) {
//     printf("%d\n", i);
    if (!dejaCalculat[i]) {
      dejaCalculat[i] = phi(i);
//       printf("phi(%d) = %.0f\n", i, dejaCalculat[i]);
      int j = 2;
      for (; (j < i) && (i * j <= n); ++j) {
        if (!relativPrime(i, j))
          continue;
        dejaCalculat[i * j] = dejaCalculat[i] * dejaCalculat[j];
//         printf("(%d * %d) phi(%d) = %.0f\n", i, j, i * j, dejaCalculat[i * j]);
      }
    }
    // RASPUNSUL CALCULAT ESTE GRESIT
    rez += dejaCalculat[i] * 2;
  }

  scrie(rez);

  return 0;
}