版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jsszwc/article/details/87902865
Project Euler 11 Largest product in a grid
题目:
https://projecteuler.net/problem=11
题意:
在给定的20×20方阵中,四个在同一方向(从下至上、从上至下、从右至左、从左至右或者对角线)上相邻的数的乘积最大是多少?
思路:
检查从左到右、从上到下、主对角线、副对角线共四个方向上连续四个数的最大乘积
代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 20 + 10;
int arr[N][N];
int toRight(int x, int y) {
int val = 1;
for(int i = 0; i < 4; i++) {
val *= arr[x][y+i];
}
return val;
}
int toDown(int x, int y) {
int val = 1;
for(int i = 0; i < 4; i++) {
val *= arr[x+i][y];
}
return val;
}
int toMainDiagonal(int x, int y) {
int val = 1;
for(int i = 0; i < 4; i++) {
val *= arr[x+i][y+i];
}
return val;
}
int toParadiagonal(int x, int y) {
int val = 1;
for(int i = 0; i < 4; i++) {
val *= arr[x+i][y-i];
}
return val;
}
int main() {
int n = 20;
//控制台读入方阵
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
scanf("%d", &arr[i][j]);
}
}
int ans = -1;
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
if(j + 4 <= 20) {
ans = max(ans, toRight(i, j));
}
if(i + 4 <= 20) {
ans = max(ans, toDown(i, j));
}
if(i + 4 <= 20 && j + 4 <= 20) {
ans = max(ans, toMainDiagonal(i, j));
}
if(i + 4 <= 20 && j - 4 >= -1) {
ans = max(ans, toParadiagonal(i, j));
}
}
}
printf("%d\n", ans);
return 0;
}
Project Euler 12 Highly divisible triangular number
题目:
https://projecteuler.net/problem=12
题意:
思路:
遍历三角形数,检查其约数是否符合要求,注意求约数个数时,复杂度是
代码:
#include <bits/stdc++.h>
using namespace std;
bool check(int val) {
int cnt = 0;
for(int i = 2; i*i <= val; i++) {
if(val % i == 0) {
if(val/i == i) {
cnt++;
} else {
cnt += 2;
}
}
}
return cnt > 500;
}
int main() {
int val = 0;
for(int i = 1; true; i++) {
val += i;
if(check(val)) {
break;
}
}
printf("%d\n", val);
return 0;
}
Project Euler 13 Large sum
题目:
https://projecteuler.net/problem=13
题意:
计算出给定的一百个50位数的和的前十位数字。
思路:
大整数加法
代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 100 + 10;
char str[N][N];
void add(char *s1, char *s2, char *s3) {
int len1 = strlen(s1), len2 = strlen(s2);
reverse(s1, s1 + len1);
reverse(s2, s2 + len2);
int carry = 0, len3 = 0;
for(int i = 0; i < len1 || i < len2; i++) {
carry += i < len1 ? s1[i]-'0' : 0;
carry += i < len2 ? s2[i]-'0' : 0;
s3[len3++] = char(carry%10 + '0');
carry /= 10;
}
if(carry) {
s3[len3++] = char(carry + '0');
}
s3[len3] = '\0';
reverse(s1, s1 + len1);
reverse(s2, s2 + len2);
reverse(s3, s3 + len3);
}
int main() {
int n = 100;
for(int i = 0; i < n; i++) {
scanf("%s", str[i]);
}
char ans[N] = {}, temp[N];
for(int i = 0; i < n; i++) {
add(str[i], ans, temp);
strcpy(ans, temp);
}
for(int i = 0; i < 10; i++) {
printf("%c", ans[i]);
}
return 0;
}
Project Euler 14 Longest Collatz sequence
题目:
https://projecteuler.net/problem=14
题意:
思路:
直接依次暴力求解每个数字的考拉兹序列项数是可以的,一个小优化就是在求的过程中,利用已知答案,减少计算量
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1000000 + 10;
int step[N];
int work(LL x) {
int cnt = 1;
while(x != 1) {
if(x & 1) {
x = 3 * x + 1;
} else {
x /= 2;
}
if(x < N && step[x] != -1) {
cnt += step[x];
break;
}
cnt++;
}
return cnt;
}
int main() {
int n = 1000000;
int num = -1, ans = -1;
memset(step, -1, sizeof(step));
for(int i = 1; i <= n; i++) {
step[i] = work(i);
if(step[i] > num) {
num = step[i];
ans = i;
}
}
printf("%d\n", ans);
return 0;
}
Project Euler 15 Lattice paths
题目:
https://projecteuler.net/problem=15
题意:
思路:
定义
为走到第i行第j列的点(这里是点),所有的不同路径数。因为要么从第
行第
列走下来,要么从第
行第j
列走过来,那么有状态转移方程:
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 20 + 10;
LL dp[N][N];
int main() {
int n = 21;
memset(dp, 0, sizeof(dp));
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
if(i == 1 && j == 1) {
dp[1][1] = 1;
} else {
dp[i][j] = dp[i][j-1] + dp[i-1][j];
}
}
}
printf("%lld\n", dp[n][n]);
return 0;
}