Project Euler 036~040

关于啥是Project Euler 详见 https://projecteuler.net/about
观前声明: .
这是个人兴趣使然的对自己入坑pe的记录,仅提供思路和部分代码;各个方面肯定都是有着优化与提升空间的,甚至在许多大佬看来这应该是初学者的浅薄而未经剪枝的丑码,如果能帮到有兴趣的人自是最好,也欢迎能醍醐灌顶的深度讨论。
大佬看到了笑笑就行,还请轻喷。
带着恶意,抬杠者...俺也喷不过您,也不能拿您咋样...毕竟这只是我个人兴趣使然的行为或者说是学习记录分享。 (说是记录,但因为是早先写的所以其实是在各种意义上公开处刑和吐槽自己 并尝试补救优化)
语言是c++,用的VS平台
本期观前提示:36~40除了40都需要频繁的用到数组与数的转化,而且本期基本莫得操作,全按定义头铁的运行即可.所以部分题可能不会怎么分析()所以我看起来会很捞...

第36题:
Double-base palindromes
Problem 36
The decimal number, 585 = 10010010012 (binary), is palindromic in both bases.
Find the sum of all numbers, less than one million, which are palindromic in base 10 and base 2.
(Please note that the palindromic number, in either base, may not include leading zeros.)
求出1000000以内所有十进制与二进制写法都为回文数的数的和。
记得第四题的回文数吗..这不就进阶版吗,多了个二进制写法也要是回文数。注意到二进制写法如果是回文数,则一定为奇数,因为0不能开头,而二进制偶数以0结尾。
对于一个数怎么变成二进制数,实际情况是比较复杂的,但如果只是正整数的话就简单得多(负数要取反加1,小数要......请自行搜索),举个例子,若数组第0位存储二进制写法的末尾数,那么比如9=2^3+2^0,第3位,第0位就为1,第1,2位为0,9的二进制写法就为1001;
详细得到步骤:若二进制表示为ana(n-1)a(n-2)……a0,那么ak=nk%2,n(k-1)=nk/2;n(n)=n
9:
9%2=1,9/2=4(整型数据自动下取整);
4%2=0,4/2=2;
2%2=0,2/2=1;
1%2=1,1/2=0;得到0后算法终止
9的二进制即为1001。对应算法:
while (n)//用A数组保存
{
A[j++] = n % 2;
n /= 2;
}
那么对于每个小于1000000的奇数,先分别存成十进制与二进制的数组,再判断十进制与二进制是否为回文数;存十进制数组懒得再讲,二进制在上面;判断,判断还要说嘛?不就个获取数组长度后头到尾尾到头看看相不相等的事实现真的不难,实在不行回去看看第四题俺怎么水的吧。
ans:872187

第37题:
Truncatable primes
Problem 37
The number 3797 has an interesting property. Being prime itself, it is possible to continuously remove digits from left to right, and remain prime at each stage: 3797, 797, 97, and 7. Similarly we can work from right to left: 3797, 379, 37, and 3.
Find the sum of the only eleven primes that are both truncatable from left to right and right to left.
NOTE: 2, 3, 5, and 7 are not considered to be truncatable primes.
3797是个有趣的质数,从左到右或从右到左不断拆掉其中的数字还为质数:797,97,7,379,37,3;只有11个质数有这种性质,求出它们的和。
上界不好求,但人家告诉我们只有11位,那么从11开始用因子确认的方式跑,或者先用个非常大的M先筛一遍,然后看看这之中有多少个符合这种性质的质数(从答案上来看不超过7位数)不过既然题干都确信只有11个质数具有此性质,那么应该是有严格的数论证明的.有兴趣的话不妨自己去搜搜,俺因为太懒就没去找了.(找到了@俺一下.俺也想看())
确认质数,遍历跑这些都不难,讲讲做成数组后提取其中某个部分。
其实也没啥好讲的,能把数组化数提取其中一部分做成数也不难,大概长这样:
int changeinter(int A[], int start, int end)
{
int i, j, sum = 0;
for (i = start, j = end - start; i <= end; i++, j--)
sum += A[i] * pow(10, j);
return sum;
}
对于每个质数判断其每个可能的分解是否为质数,分解函数如上;判断质数可以跑表也能直接判断(规模不大 头铁无伤)真的是莫得操作的题...
ans:748317

第38题:
Pandigital multiples
Problem 38
Take the number 192 and multiply it by each of 1, 2, and 3:
192 × 1 = 192,192 × 2 = 384,192 × 3 = 576
By concatenating each product we get the 1 to 9 pandigital, 192384576. We will call 192384576 the concatenated product of 192 and (1,2,3)
The same can be achieved by starting with 9 and multiplying by 1, 2, 3, 4, and 5, giving the pandigital, 918273645, which is the concatenated product of 9 and (1,2,3,4,5).
What is the largest 1 to 9 pandigital 9-digit number that can be formed as the concatenated product of an integer with (1,2, ... , n) where n > 1?
如果让192与(1,2,3)中的每位数字分别相乘得到(192,384,576),组合成一个9位数192384576,正好能不多不少的囊括1~9的所有数字,用9乘(1,2,3,4,5)也能得到同样的结果918273645,找到用这种方式得到的最大的9位数。
简单来说,就是一个整数n与(1,2,3...,k)的组合,先来分析下上界,要得到的是个9位数,所以k肯定小于等于9,不然就会得到9位数以上了,同样因为题设要求k>1,所以整数上界为10000(不然10000与(1,2)的组合会得到10位数)
那么检验数n与(1,...,k)的代码要怎么写呢?
其实也是很简单的思路,现用一个数组储存每个i*n,再把它们缝合到一个更大的数组B[100]上,如果不是9位数可以直接判断匹配失败,如果是9位数再把其中每个数记录到C上,比如定义数组C[10],C[B[i]]=1,表示B[i]出现过,遍历记录完B后再去看C[1~9]是否都出现过;
或者将B直接存到C里再对C使用sort函数排序,排完序后直接验证C[i]是否为i。
不懂事时写的丑码 仅供参考:
int checken(int n, int k)//整数n为(1,2...,k)的整合;
{
int A[10], i, j, B[1000];
for (i = 1; i <= k; i++)
A[i] = n * i;
for (i = 1, j = 0; i <= k; j = change(B, A[i++], j));//B储存整合后的数,j储存B位数;
if (j != 9)return 0;
int C[9];
for (i = 0; i < 9; i++)
C[i] = B[i];
sort(C, 0, 8);
for (i = 0; i < 9; i++)
if (C[i] != i + 1)return 0;
return changeinter(B, 0, 8);
}
调用的2个函数功能分别为int changeinter(int A[], int start, int end)//将数组A中s->end的一段转化为数字;上一题就有;
int change(int A[], int n,int start)//将n做成数组其初始位储存在A的start上,返回n的结尾数+1;
{
int i, j = 0;
while (n / (int)pow(10, j))
{
j++;
}
for (i = start; i < j + start; i++)
A[i] = (n / (int)pow(10, j + start - i - 1)) % 10;
return i;
}
这3个函数都是早年写的.感觉不太干净利落 仅供参考.知道实现思路后诸位应该能写出比俺的看的更容易入眼的代码.
答案是9327与{1,2}形成的数。
ans:932718654

第39题:
Integer right triangles
Problem 39
If p is the perimeter of a right angle triangle with integral length sides, {a,b,c}, there are exactly three solutions for p = 120.
{20,48,52}, {24,45,51}, {30,40,50}
For which value of p ≤ 1000, is the number of solutions maximised?
若p是整数边长的直角三角形的周长,那么对于p=120能够找到3个直角三角形{20,48,52}, {24,45,51}, {30,40,50};对于p<=1000,p取什么值时找到的直角三角形数量最多。
这题肯定有比我更好的解法,但看到规模这么小,我,莫得感情,莫得思考,莫得操作,化身头铁机器。
判断直角三角形:
int checkright(int a, int b, int p)//p为周长;
{
int c = p - a - b;
if (a + b < c || a + c < b || b + c < a)return 0;
if (a * a + b * b == c * c)return 1;
if (a * a + c * c == b * b)return 1;
if (b * b + c * c == a * a)return 1;
return 0;
}
判断p的解:
int nump(int p)//会有重复,结果除以3
{
int a, b, num = 0;
for (a = 1; a <= p / 2; a++)
for (b = a + 1; b <= p / 2; b++)
if (checkright(a, b, p))
num++;
return num / 3;
}
主函数头铁的跑...到1000为止
总共有8个;
ans:840

第40题:
Champernowne's constant
Problem 40
An irrational decimal fraction is created by concatenating the positive integers:
0.123456789101112131415161718192021...
It can be seen that the 12th digit of the fractional part is 1.
If dn represents the nth digit of the fractional part, find the value of the following expression.
d1 × d10 × d100 × d1000 × d10000 × d100000 × d1000000
将所有非负整数连到一起形成一个有规律可循的无理数0,1,2,3,4...->0.1234567891011...
第12位是1,那么第1位×第10位×...×第1000000位是多少?
这应该是小学生找规律求余求商的题吧?建议手算。
比如算第100位,可知1~9占满了1~9位,剩91位,现在看2位数,91/2=45...1,所以从10开始经过45个2位数后到达第90位,第45个2位数是54,4刚好占到第90位,下一个两位数55,第一个5占到第91位,所以d100=5...用这个思路分析一下真的不难 差不多几分钟就能写出来:
d1=1,d10=1,d100=5,d1000=3,d10000=7,d100000=2,d1000000=1;
手算之余 实在太懒也可以敲代码实现这个思路:
int nlength(int n)
{
if (n == 0)return 1;
int dight = 0;
while (n)
{
dight++;
n /= 10;
}
return dight;
}
int position(int n)
{
if (n < 10)return n;
int sum = 9, presum = 0, j = 1;
while (n - sum > 0)
{
presum = sum;
j++;
sum += j * 9 * (int)pow(10, j - 1);
}
int nyu = n - presum;
int nx = nyu / j, ny = nyu % j;
nx += pow(10, j - 1);
return nx / (int)pow(10, nlength(nx) - ny) % 10;
}
太简单就不解释了,实际上完全不需要代码的。
ans:210

这期感觉俺显得很捞..毕竟这几道题没啥操作,要么按定义要么头铁...
快乐BF快乐节能~
(希望各位也能体会到铁憨憨跑题的快乐吧(雾)
那么.有缘再见.

