Project Euler Problem 104 Pandigital Fibonacci ends

Pandigital Fibonacci ends

Problem 104

The Fibonacci sequence is defined by the recurrence relation:

Fn = Fn−1 + Fn−2, where F1 = 1 and F2 = 1.

It turns out that F541, which contains 113 digits, is the first Fibonacci number for which the last nine digits are 1-9 pandigital (contain all the digits 1 to 9, but not necessarily in order). And F2749, which contains 575 digits, is the first Fibonacci number for which the first nine digits are 1-9 pandigital.

Given that Fk is the first Fibonacci number for which the first nine digits AND the last nine digits are 1-9 pandigital, findk.


C++:

#include <iostream>
#include <cstdio>

using namespace std;

typedef unsigned long long ULL;

const ULL ulmax = ~((ULL)0);
const ULL ulmax10 = ulmax / 10;
const ULL N = 1000000000;

bool ispandigital(ULL n) {
    int digits = 0b1111111110;

    while (n) {
        digits ^= 1 << (n % 10);
        n /= 10;
    }

    return !digits;
}

int main()
{
    ULL f1l=1, f2l=1, nextleft;
    ULL f1r=1, f2r=1, nextright;
    int k = 2;

    for(;;) {
        k++;

        nextright = (f1r + f2r) % N;
        f1r = f2r;
        f2r = nextright;

        nextleft = f1l + f2l;
        if(nextleft >= ulmax10) {
            nextleft /= 10;
            f2l /= 10;
        }
        f1l = f2l;
        f2l = nextleft;

        while(nextleft > N)
            nextleft /= 10;
        if(ispandigital(nextleft) && ispandigital(nextright)) {
            cout << k << endl;
            break;
        }
    }

    return 0;
}


C++:

#include <iostream>
#include <cstring>
#include <cmath>

using namespace std;

const long N = 1000000000;

const double r5 = sqrt(5.0);
const double lgr = log10((1.0 + r5) / 2.0);
const double lr5 = log10(r5);

bool ispandigital(long v)
{
    int digits[10], d;

    memset(digits, 0, sizeof(digits));

    while(v) {
        d = v % 10;
        if(digits[d])
            return false;
        digits[d] = 1;
        v /= 10;
    }
    if(digits[0])
        return false;

    for(int i=1; i<10; i++)
        if(digits[i] == 0)
            return false;

    return true;
}

bool ispandigital2(long n) {
    int digits = 0b1111111110;

    while (n) {
        digits ^= 1 << (n % 10);
        n /= 10;
    }

    return !digits;
}

int main()
{
    long f1=1, f2=1, next, k=2;

    for(;;) {
        k++;
        next = (f1 + f2) % N;
        if(ispandigital2(next)) {
            double d = (double)k * lgr - lr5;
            long t = (long)pow(10.0, 8.0 + d - floor(d));

            if(ispandigital2(t)) {
                cout << k << endl;
                break;
            }
        }

        f1 = f2;
        f2 = next;
    }

    return 0;
}

参考链接:Project Euler problem 104

posted on 2017-03-29 11:38  海岛Blog  阅读(212)  评论(0编辑  收藏  举报

导航