疯狂debug Google Kick Start 2018 Round A 第一题

题目大意:

给你一个数,可以做加法,可以做减法,每次只能加1,减1

需要最后每一位都是偶数,问需要加(或减)多少次

 

破题:

找到一个数离它最近的每一位都是偶数的数,思路很简单

这种数学题最适合举例子找思路

 

如:355 从最高位开始,‘3’,则已经限定了范围(无非在比它大的数里找最小的,比它小的找最大的)

做加法:400(4开头最小的)

做减法:288(2开头最大的)

比较400-355和355-288哪个小就好

 

再比如:2594从最高位开始,检测到‘5’

做加法:2600

做减法:2488

这时比较594和600以及488的距离即可

总之,就是从高找到第一个奇数位,从那一位开始,该位加1,其之后的位全0;该位减1,其之后位全8

 

找BUG

Bug 1

大数据集:1~10^16

所以要用long long int

注意:一般的机器 long int 和int 都是4bytes,所以long int真的很鸡肋

不信自测:

#include<cstdio>
#include<cstdlib>
using namespace std;
int main() {
    printf("%d\n", sizeof(short int));
    printf("%d\n", sizeof(int));
    printf("%d\n", sizeof(long int));
    printf("%d\n", sizeof(long long int));
    printf("%d\n", sizeof(float));
    printf("%d\n", sizeof(double));
    system("pause");
}

 

 Bug 2

‘9’的特殊情况

但凡第一个奇数位是9,就根本不能采用加法,因为会有进位!

否则,298  做加法:300    做减法:288  做加法结果更近但是错了

 

Bug 3

居然发生了除0错误,代码中只有一处除法逻辑上根本不会除0

但是忽略了整数溢出的问题,溢出之后就有问题

所以把所有中间变量都改成long long int 之后,通过✔

 

上代码(有注释)

 ​

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
using namespace std;
long long int mypow(int x,int y) {
    long long int res=1;
    for (int i = 1; i <= y; i++)
        res *= x;
    return res;
}
int main() {
    int rounds;
    long long int aim;
    long long int result = 0;
    int a[20];
    int i = 0;
    cin >> rounds;

    while (i<rounds) {
        result = 0;
        cin >> aim;
        long long int n = 10; int j = 0;
        while (1) {
            a[j] = (aim%n) / (n / 10);
            if (aim/n==0) break;
            n = n * 10; j++;
        }  //数组里面一个存一位,如123中,a[2]=1,a[1]=2,a[0]=3

        for (int k = j; k >= 0; k--) {
            if (a[k] % 2) {
                if (a[k] != 9) {
                    long int now = 0, x1, x2, tmp = 0;
                    for (int k1 = k; k1 >= 0; k1--) now += a[k1] * mypow(10, k1); 
                    //计算从这一奇数位开始的数的值,如22390中的390
                    for (int k2 = k - 1; k2 >= 0; k2--) tmp += 8 * mypow(10, k2);
                    //计算从这22390变成22488的中间值
                    x1 = (a[k] + 1)*mypow(10, k) - now;
                    x2 = now - ((a[k] - 1)*mypow(10, k) + tmp);
                    if (x1 > x2) result = x2;
                    else result = x1;
                }
                else { //9情况特殊,只做减法
                    long int tmp = 0,now=0;
                    for (int k2 = k - 1; k2 >= 0; k2--) tmp += 8 * mypow(10, k2);
                    for (int k1 = k; k1 >= 0; k1--) now += a[k1] * mypow(10, k1);
                    result= now - (a[k] - 1)*mypow(10, k) - tmp;
                    
                }
                break;

            }
        }
        cout << "Case #" << i+1 << ": " << result << '\n';
        i++;
    }
    return 0;
}
 

Problem

Supervin has a unique calculator. This calculator only has a display, a plus button, and a minus button. Currently, the integer N is displayed on the calculator display.

Pressing the plus button increases the current number displayed on the calculator display by 1. Similarly, pressing the minus button decreases the current number displayed on the calculator display by 1. The calculator does not display any leading zeros. For example, if 100 is displayed on the calculator display, pressing the minus button once will cause the calculator to display 99.

Supervin does not like odd digits, because he thinks they are "odd". Therefore, he wants to display an integer with only even digits in its decimal representation, using only the calculator buttons. Since the calculator is a bit old and the buttons are hard to press, he wants to use a minimal number of button presses.

Please help Supervin to determine the minimum number of button presses to make the calculator display an integer with no odd digits.

Input

The first line of the input gives the number of test cases, TT test cases follow. Each begins with one line containing an integer N: the integer initially displayed on Supervin's calculator.

Output

For each test case, output one line containing Case #x: y, where x is the test case number (starting from 1) and y is the minimum number of button presses, as described above.

Limits

1 ≤ T ≤ 100.
Time limit: 20 seconds per test set.
Memory limit: 1GB.

Small dataset (Test set 1 - Visible)

1 ≤ N ≤ 105.

Large dataset (Test set 2 - Hidden)

1 ≤ N ≤ 1016.

Sample


Input 
 

Output 
 
4
42
11
1
2018

  
Case #1: 0
Case #2: 3
Case #3: 1
Case #4: 2

  

In Sample Case #1, the integer initially displayed on the calculator has no odd digits, so no button presses are needed.

In Sample Case #2, pressing the minus button three times will cause the calculator to display 8. There is no way to satisfy the requirements with fewer than three button presses.

In Sample Case #3, either pressing the minus button once (causing the calculator to display 0) or pressing the plus button once will cause the calculator to display an integer without an odd digit.

In Sample Case #4, pressing the plus button twice will cause the calculator to display 2020. There is no way to satisfy the requirements with fewer than two button presses.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值