第16题
这个题是求
21000
在十进制表示下各位数字的和。
我没想到很好的算法,只想到一个
O(n2)
的高精度处理,直接求出结果,再一位一位加起来。
int main(){
int num[1000],len=0;
num[0]=1;
for (int i=1;i<=1000;i++){
int tmp=0;
for (int j=0;j<=len;j++){
num[j]<<=1;
if(tmp==1){
tmp=0;
num[j]++;
}
if (num[j]>9){
num[j]-=10;tmp=1;
}
}
if (tmp) num[++len]=1;
}
int ans=0;
for (int i=0;i<=len;i++) ans+=num[i];
cout<<ans<<endl;
return 0;
}
第17题
题目求的是1-1000这1000个数用英文表示出来总共有多少个字母。
这个题是我手算的,并没有写代码。我觉得这时候写代码反而是一个吃力不讨好的过程。感觉这题可以给差评了。
容易发现:
1,2,3,……,98,99这99个数是每一百个数就要出现一次的,所以一共出现了10次,答案是
854∗10=8540
;
one hundred,two hundred,……,nine hundred这些表示百位的数各出现了100次,答案是
99∗100=9900
;
而用于连接百位和其余两位的and单词从100开始,每一百个数出现99次,答案是
3∗99∗9=2673
;
剩下的是one thousand这个单词,包含11个字母。
全部加起来就是答案21124。
第18题
题目来源ProjectEuler
这个题求顶点到最层的各路径中最大路径和是多少,是动态规划的经典入门题。
考虑每个数到底层的最大路径。
dp[i][j]=num[i][j]+max(dp[i+1][j],dp[i+1][j+1]),[i][j]
表示第i行的第j个数。
尽管这个题二维数组并不会浪费太多空间,但依然可以压缩成一维的dp数组。
int dp[16],num[16][16];
int main(){
int n=15;
for (int i=1;i<=n;i++){
for (int j=1;j<=i;j++){
num[i][j]=read();
}
}
for (int i=1;i<=n;i++) dp[i]=num[n][i];
for (int i=n-1;i>=1;i--){
for (int j=1;j<=i;j++){
dp[j]=max(dp[j]+num[i][j],dp[j+1]+num[i][j]);
}
}
cout<<dp[1]<<endl;
return 0;
}
第19题
这个题求的是1901-1-1至2000-12-31的时间中,有多少个星期天恰好是某个月的第一天。我们将周日当做每个星期的第0天。
day0
与
dayx
的关系就是
dayx=(day0+x)mod7
其他月份都是定的,只有2月份有平闰年之分,又考虑到这一段时间内所有被4整除的年份都是闰年。模拟一遍就好。
int main(){
int day=(1+356)%7,ans=0;
for (int i=1901;i<=2000;i++){
for(int j=1;j<=12;j++){
if (day==0) ans++;
if (j==2){
if (i%4==0) day=(day+29)%7;
}
else{
if (j==1||j==3||j==5||j==7||j==8||j==10||j==12)
day=(day+31)%7;
else day=(day+30)%7;
}
}
}
cout<<ans<<endl;
return 0;
}
第20题
这个题是求 100! 的十进制表示下各位数字的和。跟16题很像,依然是只会高精度处理的做法。
int num[600],len;
int main(){
num[1]=1;len=1;
int n=read();
for (int i=2;i<=n;i++){
int tmp=0;
for (int j=1;j<=len;j++){
num[j]*=i;
num[j]+=tmp;
tmp=num[j]/10;
num[j]%=10;
}
while(tmp){
num[++len]=tmp%10;
tmp/=10;
}
}
int ans=0;
for (int i=len;i>=1;i--){
ans+=num[i];
}
cout<<ans<<endl;
return 0;
}
本文介绍了Project Euler的第16到20题的解题思路。第16题通过高精度计算求解2^1000的十进制各位数字之和;第17题手算1-1000英文表示的字母总数,得出21124的结果;第18题是动态规划的经典问题,通过一维动态规划数组求解最大路径和;第19题通过模拟计算1901年至2000年有多少个星期天是月份的第一天;第20题类似第16题,求解100!的十进制各位数字之和。
274

被折叠的 条评论
为什么被折叠?



