欧拉计划--C++编程突破10

欧拉计划–C++编程突破10

Problem 19
You are given the following information, but you may prefer to do some research for yourself.
1 Jan 1900 was a Monday.
Thirty days has September,
April, June and November.
All the rest have thirty-one,
Saving February alone,
Which has twenty-eight, rain or shine.
And on leap years, twenty-nine.
A leap year occurs on any year evenly divisible by 4, but not on a century unless it is divisible by 400.
How many Sundays fell on the first of the month during the twentieth century (1 Jan 1901 to 31 Dec 2000)?

问题19
你得到了以下信息,但你可能更愿意为自己做一些研究。
1900年1月1日是星期一。 三十天有九月,四月,六月和十一月。 其余的都有三十一天,除了二月,有二十八天。(我服了,google生草机) 在闰年,有二十九天。 闰年发生在任何能被4整除的年份上,但除非能被400整除,否则不会发生在一个世纪上。 在二十世纪(1901年1月1日至2000年12月31日),的第一个月的第一天有多少个星期日?

解题思路:无非是计算日子,将计算从第一天到每年的第一个月的日子对7取模,就能够得出对应的月的第一天是星期几,在计算是星期天的个数就可以了。然后注意2月和闰年的特点,计算日子的时候不要忽略掉。

#include<stdio.h>

int WhichDay(int y, int m, int d) {
    if (m == 1 || m == 2) {
        --y; m += 12;
    }
    int w;
    w = (d + 2 * m + 3 * (m + 1) / 5 + y + y / 4 - y / 100 + y / 400) % 7;
    return w;
}

int main() {
    int sunday = 0;
    for (int y = 1901; y < 2001; ++y) {
        for (int m = 1; m <= 12; ++m) {
            if (WhichDay(y, m, 1) == 6)
            ++sunday;
        }
    }
    printf("%d\n", sunday);
    return 0;
}

验证answer = 171

Problem 20
n! means n × (n − 1) × … × 3 × 2 × 1
For example, 10! = 10 × 9 × … × 3 × 2 × 1 = 3628800,
and the sum of the digits in the number 10! is 3 + 6 + 2 + 8 + 8 + 0 + 0 = 27.
Find the sum of the digits in the number 100!

问题20
n! 意思是n×(n−1)×.×3。2×1
例如,10! =10×9×…×3×2×1=3628800,
以及10!结果的各位之和是362880=27。
求数100中的位数的和!

解题思路:方法很简单,还是像之前的一样使用数组记录每位的数字,毕竟是计算每位的数字的和,不是直接记录数字,所以比较简单,把数组开大点,100!得到的结果相当大了。数组存储每位数字的方法前面已经有提过,移位模十不再重复。

#include<stdio.h>
#define max_n 10000

int arr[max_n + 5] = {0};

int main() {
    arr[0] = arr[1] = 1;
    for(int i = 1; i <= 100; i++) {
        for(int j = 1; j <= arr[0]; j++) {
            arr[j] *= i;
    }
        for(int k = 1; k <= arr[0]; k++) {
            if(arr[k] < 10) continue;
            arr[k + 1] += arr[k] / 10;
            arr[k] %= 10;
            arr[0] += (k == arr[0]);
        } 
    }
    int sum = 0;
    for(int i = arr[0]; i >= 1; i--) {
        sum += arr[i];
    }
    printf("%d",sum);
    return 0;
}

验证answer = 648

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值