project euler 315

更好的阅读体验

problems

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uj2jzAjx-1631859277324)(https://projecteuler.net/project/images/p315_clocks.gif)]

Sam and Max are asked to transform two digital clocks into two “digital root” clocks.
A digital root clock is a digital clock that calculates digital roots step by step.

When a clock is fed a number, it will show it and then it will start the calculation, showing all the intermediate values until it gets to the result.
For example, if the clock is fed the number 137, it will show: “137” → “11” → “2” and then it will go black, waiting for the next number.

Every digital number consists of some light segments: three horizontal (top, middle, bottom) and four vertical (top-left, top-right, bottom-left, bottom-right).
Number “1” is made of vertical top-right and bottom-right, number “4” is made by middle horizontal and vertical top-left, top-right and bottom-right. Number “8” lights them all.

The clocks consume energy only when segments are turned on/off.
To turn on a “2” will cost 5 transitions, while a “7” will cost only 4 transitions.

Sam and Max built two different clocks.

Sam’s clock is fed e.g. number 137: the clock shows “137”, then the panel is turned off, then the next number (“11”) is turned on, then the panel is turned off again and finally the last number (“2”) is turned on and, after some time, off.

For the example, with number 137, Sam’s clock requires:

137” : (2 + 5 + 4) × 2 = 22 transitions (“137” on/off).
11” : (2 + 2) × 2 = 8 transitions (“11” on/off).
2” : (5) × 2 = 10 transitions (“2” on/off).
For a grand total of 40 transitions.

Max’s clock works differently. Instead of turning off the whole panel, it is smart enough to turn off only those segments that won’t be needed for the next number.
For number 137, Max’s clock requires:

137”: 2 + 5 + 4 = 11 transitions (“137” on)
7 transitions (to turn off the segments that are not needed for number “11”).
11”: 0 transitions (number “11” is already turned on correctly)
3 transitions (to turn off the first “1” and the bottom part of the second “1”;
the top part is common with number “2”).
2”: 4 transitions (to turn on the remaining segments in order to get a “2”)
5 transitions (to turn off number “2”).
For a grand total of 30 transitions.

Of course, Max’s clock consumes less power than Sam’s one.
The two clocks are fed all the prime numbers between A = 1 0 7 A = 10^7 A=107 and B = 2 × 1 0 7 B = 2×10^7 B=2×107.
Find the difference between the total number of transitions needed by Sam’s clock and that needed by Max’s one.## translation

translate

现在有8数码管,每次开启or关闭一节的能量是 1 1 1 ,现在有两种方式展示数字:

  1. 先展示数字 a a a,关闭所有的灯管,然后展示数字 b b b,关闭所有的灯管,以此类推。
  2. 先展示数字 a a a,关闭 b b b 不需要的灯管,保留 a a a b b b 都需要的灯管,然后打开仅 b b b 需要的灯管。

显然第二种方式更节能。

现在这个展示一个数字的逻辑是,先展示数字 a a a,然后展示 a a a 10 10 10 进制下每一位的和,然后展示 a a a 10 10 10 进制下诸位和的诸位和,以此类推,直到剩下一位。然后全熄灭。

现在需要展示 [ 1 0 7 , 2 ∗ 1 0 7 ] [10^7, 2*10^7] [107,2107] 中所有的质数,问你第二种方式比第一种方式节能多少。

solution

纯模拟,先用筛法筛出我们需要的数字,然后枚举每个质数,算贡献即可。

solution.cpp

#include<bits/stdc++.h>

using namespace std;
int trans[10][10];

void init() {/*{{{*/
    bool light[10][10];
    memset(light, false, sizeof(light));
    light[0][1] = light[0][2] = light[0][3] = light[0][5] = light[0][6] = light[0][7] = true;
    light[1][3] = light[1][6] = true;
    light[2][1] = light[2][3] = light[2][4] = light[2][5] = light[2][7] = true;
    light[3][1] = light[3][3] = light[3][4] = light[3][6] = light[3][7] = true;
    light[4][2] = light[4][3] = light[4][4] = light[4][6] = true;
    light[5][1] = light[5][2] = light[5][4] = light[5][6] = light[5][7] = true;
    light[6][1] = light[6][2] = light[6][4] = light[6][5] = light[6][6] = light[6][7] = true;
    light[7][1] = light[7][2] = light[7][3] = light[7][6] = true;
    light[8][1] = light[8][2] = light[8][3] = light[8][4] = light[8][5] = light[8][6] = light[8][7] = true;
    light[9][1] = light[9][2] = light[9][3] = light[9][4] = light[9][6] = light[9][7] = true;
    for (int i = 0; i < 10; i++)
        for (int j = 0; j < 10; j++) {
            trans[i][j] = 0;
            for (int x = 1; x <= 7; x++) {
                if (light[i][x] != light[j][x]) trans[i][j]--;
                if (light[i][x]) trans[i][j]++;
                if (light[j][x]) trans[i][j]++;
            }
        }
}/*}}}*/
void cal(int a, int &len, int &sum) {
    len = sum = 0;
    while (a) {
        len++;
        sum += a % 10;
        a /= 10;
    }
}
int cal(int a, int b) {
    int ret = 0;
    while (b) {
        ret += trans[a % 10][b % 10];
        a /= 10;
        b /= 10;
    }
    return ret;
}
int cal(int a) {/*{{{*/
    int len, sum;
    int ret = 0;
    //cout<<a;
    while (a) {
        cal(a, len, sum);
        if (a == sum) return ret;
        ret += cal(a, sum);
        a = sum;
        ///cout<<"->"<<a;
    }
    //cout<<endl;
    return ret;
}/*}}}*/
bool p[20000007];
int main() {
    init();
    memset(p, false, sizeof(p));
    long long ans = 0;
    for (int i = 2; i <= 20000000; i++) {
        if (!p[i]) {
            for (int j = i << 1; j <= 20000000; j += i) p[j] = true;
            if (i >= 10000000) ans += cal(i);
        }
    }
    cout << ans << endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zuhiul

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值