Cod sursa(job #852763)

Utilizator danp.maneaManea Petre-Dan danp.manea Data 11 ianuarie 2013 18:29:26
Problema Fractii Scor 0
Compilator c Status done
Runda Arhiva de probleme Marime 3.83 kb
#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();
}