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;
}