2013年8月15日 星期四

ProjectEuler 60 -- Backtracking TLE

#include <iostream>
#include <sstream>
#include <string>
#include <stdio.h>

#define SIEVE_RANGE (1000035)
#define PRIME_COUNT (78500)
#define N (5)

bool sieve_visited[SIEVE_RANGE] = {};
long long primes[PRIME_COUNT] = {};

void Sieve()
{
    int curr_pos = 0;
    for (long long i = 2; i < SIEVE_RANGE; i++)
    {
        if (!sieve_visited[i])
        {
            primes[curr_pos] = i;
            curr_pos++;
            for (long long j = i + i; j < SIEVE_RANGE; j += i)
            {
                sieve_visited[j] = true;
            }
        }
    }
}

bool IsPrime(long long n) 
{
    for (long long i = 0; 
        (i < PRIME_COUNT) && (primes[i] * primes[i] <= n); i++) 
    {
        if (n == primes[i]) 
        {
            return true;
        }
        if (n % primes[i] == 0) 
        {
            return false;
        }
    }
    return true;
}

template <class T>
inline std::string to_string(const T& t)
{
    std::stringstream builder;
    builder << t;
    return builder.str();
}

template <class T>
inline T to_type(const std::string& s)
{
    std::stringstream builder(s);
    T t;
    builder >> t;
    return t;
}

long long solution_vector[N] = {};

bool IsValid(int dimension)
{
    long long n;
    for (int i = 0; i < dimension; i++)
    {
        for (int j = i+1; j < dimension; j++)
        {
            n = to_type<long long>(
                to_string<long long>(solution_vector[i]) +
                to_string<long long>(solution_vector[j]));
            if (!IsPrime(n))
            {
                return false;
            }

            n = to_type<long long>(
                to_string<long long>(solution_vector[j]) +
                to_string<long long>(solution_vector[i]));
            if (!IsPrime(n))
            {
                return false;
            }
        }
    }
    return true;
}

void DebugSolutionVector(int dimension)
{
    for (int i = 0; i < dimension; i++)
    {
        printf("%d ", solution_vector[i]);
    }
    printf("\n");
}

void Backtrack(int dimension)
{
    if (!IsValid(dimension))
    {
        return;
    }
    DebugSolutionVector(dimension);
    if (dimension == N)
    {
        DebugSolutionVector(dimension);
        return;
    }
    for (int i = 0; i < PRIME_COUNT; i++)
    {
        if (dimension == 0 || solution_vector[dimension-1] < primes[i])
        {
            solution_vector[dimension] = primes[i];
            Backtrack(dimension + 1);
        }
    }
}

void Solve()
{
    Backtrack(0);
}

int main(int argc, char* argv[])
{
    Sieve();
    Solve();
    return 0;
}

沒有留言:

張貼留言