Project Euler C/C++ 解题记录

这题没什么好说的。

#include<iostream>
using namespace std;


int main() {
    ios::sync_with_stdio(false);
    unsigned int sum = 0U;

    for (unsigned short num = 1U; num < 1000U; num++) {
        if (!(num % 3U && num % 5U)) {
            sum += num;
        }
    }

    cout << sum << endl;
    return 0;
}

观察可以发现,每隔2个斐波那契数就会有一个偶数。
a+=b;b+=a; 可以前进两个数,且效率更高。

#include<iostream>
using namespace std;


int main() {
    ios::sync_with_stdio(false);
    unsigned int a = 2U, b = 3U, sum = 0U, temp;

    while (a < 4000000U) {
        sum += a;
        a += b;
        b += a;
        temp = a + b;
        a = b;
        b = temp;
    }

    cout << sum << endl;
    return 0;
}

没有优化。

#include<iostream>
using namespace std;


int main() {
    ios::sync_with_stdio(false);
    unsigned long long divisor = 3ULL, num;
    for (num = 600851475143ULL; num != 1U; num % divisor ? divisor += 2U : num /= divisor);
    cout << divisor << endl;
    return 0;
}

把所有的两个三位数的积都求出来,然后比较。同样没有优化。

#include<iostream>
using namespace std;


int main() {
    ios::sync_with_stdio(false);
    unsigned int i, j, k, temp, reversed, res = 0U;

    for (i = 100U; i < 1000U; i++) {
        for (j = 100U; j < 1000U; j++) {
            if ((k = i * j) > res) {
                reversed = 0U;
                temp = k;

                while (temp) {
                    reversed = reversed * 10U + temp % 10U;
                    temp /= 10U;
                }

                if (reversed == k) {
                    res = k;
                }
            }
        }
    }

    cout << res << endl;
    return 0;
}

就是求1-20的最小公倍数。

#include<iostream>
using namespace std;


int main() {
    ios::sync_with_stdio(false);
    unsigned int a, b, c, i, res = 1U;

    for (i = 2; i <= 20; i++) {
        a = res;
        b = i;
        while (b) {
            c = a % b;
            a = b;
            b = c;
        }

        res *= i / a;
    }

    cout << res << endl;
    return 0;
}

暴力,没什么好说的。

#include<iostream>
using namespace std;


int main() {
    ios::sync_with_stdio(false);
    unsigned long long a = 0, b = 0;

    for (unsigned short i = 1; i <= 100; i++) {
        a += i;
        b += i * i;
    }

    cout << a * a - b << endl;
    return 0;
}

埃式筛法。

#include<iostream>
#define MAX 2000000U
using namespace std;
bool primes[MAX];


int main() {
    ios::sync_with_stdio(false);
    unsigned long long sum = 2U;
    unsigned int num, idx, step;

    for (num = 3U; num < MAX; num += 2U) {
        if (!primes[num]) {
            sum += num;
            step = num << 1U;

            for (idx = num + step; idx < MAX; idx += step) {
                primes[idx] = true;
            }
        }
    }

    cout << sum << endl;
    return 0;
}

没有优化。

#include<iostream>
#include<cmath>
using namespace std;


int main() {
    ios::sync_with_stdio(false);
    int i, j = 1, count = 0, k;
    double root;

    for (i = 1;; i += ++j) {
        root = sqrt(i);
        count = 0;

        for (k = 2; k < root; ++k) {
            if (!(i % k)) {
                ++count;
            }
        }

        if (fmod(root, 1) ? count > 249 : count > 250) {
            cout << i << endl;
            return 0;
        }
    }
}

设置缓存,如果某一步的结果比原数小了,那么直接从缓存中取就可以了。

#include<iostream>
using namespace std;
unsigned num, maxnum = 0, temp;
unsigned short len, maxlen = 0, cache[1000000];


int main() {
    ios::sync_with_stdio(false);

    for (num = 1; num < 1000000; ++num) {
        len = 0;
        temp = num;

        while (temp != 1) {
            if (temp < num) {
                len += cache[temp];
                break;
            }

            ++len;

            if (temp & 1) {
                temp *= 3;
                ++temp;
            }
            else {
                temp >>= 1;
            }
        }

        if (len > maxlen) {
            maxlen = len;
            maxnum = num;
        }

        cache[num] = len;
    }

    cout << maxnum << endl;
    return 0;
}

没什么好说的。

#include<iostream>
#define max(a, b) (a > b ? a : b)
using namespace std;


int main() {
    ios::sync_with_stdio(false);
    unsigned char row = 14, column;
    unsigned short data[15][15] = {
        {75},
        {95, 64},
        {17, 47, 82},
        {18, 35, 87, 10},
        {20, 04, 82, 47, 65},
        {19, 01, 23, 75, 03, 34},
        {88, 02, 77, 73, 07, 63, 67},
        {99, 65, 04, 28, 06, 16, 70, 92},
        {41, 41, 26, 56, 83, 40, 80, 70, 33},
        {41, 48, 72, 33, 47, 32, 37, 16, 94, 29},
        {53, 71, 44, 65, 25, 43, 91, 52, 97, 51, 14},
        {70, 11, 33, 28, 77, 73, 17, 78, 39, 68, 17, 57},
        {91, 71, 52, 38, 17, 14, 91, 43, 58, 50, 27, 29, 48},
        {63, 66, 04, 68, 89, 53, 67, 30, 73, 16, 69, 87, 40, 31},
        {04, 62, 98, 27, 23, 9, 70, 98, 73, 93, 38, 53, 60, 04, 23}
    };

    while (column = row--) {
        while (column--) {
            data[row][column] += max(data[row + 1][column], data[row + 1][column + 1]);
        }
    }

    cout << data[0][0] << endl;
    return 0;
}
#include<iostream>
using namespace std;


int main() {
    ios::sync_with_stdio(false);
    unsigned long long res = 0, temp;
    unsigned short i, j;

    for (i = 1000; i; i--) {
        temp = j = i;

        while (--j) {
            temp *= i;
            temp %= 10000000000;
        }

        res += temp;
    }

    cout << res % 10000000000 << endl;
    return 0;
}

动态规划

#include<stdio.h>
unsigned arr[80][80];


inline unsigned min(unsigned a, unsigned b) {
    return a < b ? a : b;
}


int main() {
    FILE* file = fopen("p081_matrix.txt", "r");
    unsigned char i, j;

    for (i = 0; i < 80; ++i) {
        for (j = 0; j < 80; ++j) {
            fscanf(file, "%u%*c", &arr[i][j]);

            if (i) {
                if (j) {
                    arr[i][j] += min(arr[i - 1][j], arr[i][j - 1]);
                }
                else {
                    arr[i][j] += arr[i - 1][j];
                }
            }
            else if (j) {
                arr[i][j] += arr[i][j - 1];
            }
        }
    }

    fclose(file);
    printf("%u", arr[79][79]);
    return 0;
}
#include<iostream>
using namespace std;
using flag=signed char;
flag cache[568];


flag calc(unsigned int x) {
    const static unsigned char map[] = { 0, 1, 4, 9, 16, 25, 36, 49, 64, 81 };
    unsigned short res = 0;

    while (x) {
        res += map[x % 10];
        x /= 10;
    }

    return cache[res] ? cache[res] : cache[res] = calc(res);
}


int main() {
    ios::sync_with_stdio(false);
    unsigned count = 0, num = 10000000;
    cache[1] = -1;
    cache[89] = 1;

    while (--num) {
        count += calc(num) == 1;
    }

    cout << count << endl;
    return 0;
}
#include<stdio.h>
#include<math.h>


int main() {
    unsigned short line, maxline;
    unsigned a, b;
    double n, maxn = 0.0L;
    FILE* file = fopen("p099_base_exp.txt", "r");

    for (line = 1; line <= 1000; ++line) {
        fscanf(file, "%u,%u", &a, &b);
        n = log(a) * b;

        if (n > maxn) {
            maxn = n;
            maxline = line;
        }
    }

    fclose(file);
    printf("%u", maxline);
    return 0;
}

把 N 平分为 k 份,k=round(N/e) 时乘积最大。
有限小数分母的因数只能包括 2 或 5 。

#define _USE_MATH_DEFINES
#include<iostream>
#include<cmath>
using namespace std;


int main() {
    ios::sync_with_stdio(false);
    int sum = 0, temp, a, b, c, i;

    for (i = 5; i <= 10000; ++i) {
        temp = round(i / M_E);

        a = temp;
        b = i;
        while (b) {
            c = a % b;
            a = b;
            b = c;
        }
        temp /= a;

        while (!(temp & 1)) {
            temp >>= 1;
        }
        while (!(temp % 5)) {
            temp /= 5;
        }

        if (temp == 1) {
            sum -= i;
        }
        else {
            sum += i;
        }
    }

    cout << sum << endl;
    return 0;
}

快速幂取模

#include<iostream>
using namespace std;


int main() {
    ios::sync_with_stdio(false);
    unsigned long long res = 1777, base, temp;

    for (unsigned short count = 1854; count; --count) {
        temp = res;
        res = 1;
        base = 1777;

        while (temp) {
            if (temp & 1) {
                res *= base;
                res %= 100000000;
            }

            base *= base;
            base %= 100000000;

            temp >>= 1;
        }
    }

    cout << res << endl;
    return 0;
}
posted @ 2020-05-16 17:02  NoneType  阅读(147)  评论(0编辑  收藏  举报