Pagini recente » Cod sursa (job #1817361) | Cod sursa (job #718960) | Cod sursa (job #316723) | Cod sursa (job #2061338) | Cod sursa (job #852763)
Cod sursa(job #852763)
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int number = 0;
int primeNumbers[80000];
int countPrime;
long long result;
typedef struct
{
int CommonMultiple;
char Count;
} CommonMultipleCount;
void readInput()
{
FILE *input = fopen("fractii.in", "r");
if (input == NULL) return;
fscanf(input, "%d", &number);
fclose(input);
}
void constructPrimeNumbers()
{
char *isPrime = (char*)malloc(1000000*sizeof(char));
isPrime[2] = 1;
for (int index = 0; index < 1000000; index++)
isPrime[index] = 1;
int currentNo = 2;
while (currentNo * currentNo <= number)
{
int multiple = currentNo * currentNo;
while (multiple <= number)
{
isPrime[multiple] = 0;
multiple = multiple + currentNo;
}
currentNo ++;
while (!isPrime[currentNo])
currentNo ++;
}
countPrime = 0;
for (int index = 2; index <= number; index++)
if (isPrime[index])
{
primeNumbers[countPrime] = index;
countPrime++;
}
}
void printSolution()
{
FILE *output = fopen("fractii.out", "w");
if (output == NULL) return;
fprintf(output, "%d", result);
fclose(output);
}
void FindAllCommonMultiples(char used[], int currentIndex, int primeDivisors[], int count, CommonMultipleCount **result, int *resultCount)
{
if (currentIndex >= count)
{
int commonMultiple = 1;
int noOfDivisors = 0;
for (int index = 0; index < count; index ++)
{
if (used[index] > 0)
commonMultiple *= primeDivisors[index];
noOfDivisors += used[index] * 1;
}
if (noOfDivisors >= 2) //we don't need prime numbers
{
(*result)[*resultCount].Count = noOfDivisors;
(*result)[*resultCount].CommonMultiple = commonMultiple;
*resultCount = *resultCount + 1;
}
return;
}
used[currentIndex] = 1;
FindAllCommonMultiples(used, currentIndex + 1, primeDivisors, count, result, resultCount);
used[currentIndex] = 0;
FindAllCommonMultiples(used, currentIndex + 1, primeDivisors, count, result, resultCount);
}
//calculates all the possible common multipliers of the prime divisors of currentNo
CommonMultipleCount* calculateMultiples(int currentNo, int primeDivisors[], int primeDivisorsCount)
{
CommonMultipleCount *result = (CommonMultipleCount *)calloc(500000, sizeof(CommonMultipleCount));
char used[12];
for (int index = 0; index < 12; index ++)
used[index] = 0;
int resultCount = 0;
FindAllCommonMultiples(used, 0, primeDivisors, primeDivisorsCount, &result, &resultCount);
return result;
}
int calculateReductibleFractionsCount(int currentNo)
{
int index = 0;
int primeDivisors[12];
char count = 0;
while (primeNumbers[index] <= currentNo && primeNumbers[index] > 0)
{
if (currentNo % primeNumbers[index] == 0)
{
primeDivisors[count] = primeNumbers[index];
count++;
}
index++;
}
CommonMultipleCount *result = calculateMultiples(currentNo, primeDivisors, count);
int redFractionsCount = 0;
for (index = 0; index < count; index++)
redFractionsCount += number / primeDivisors[index];
index = 0;
while (result[index].Count > 0)
{
redFractionsCount -= (number / (result[index].CommonMultiple)) * (result[index].Count - 1);
index ++;
}
free(result);
return redFractionsCount;
}
void constructSolution()
{
result = number;
for (int index = 2; index <= number; index++)
{
//TODO avoid processing prime NOs.
int indexFractionsCount = number;
int reductibleFractionsCount = calculateReductibleFractionsCount(index);
result = result + indexFractionsCount - reductibleFractionsCount;
}
}
void getSolution()
{
readInput();
constructPrimeNumbers();
constructSolution();
printSolution();
}
int main()
{
getSolution();
}