Google kickstart笔试题
Supervin有一个独特的计算器。
此计算器由一个显示器,一个加号按钮和一个减号按钮构成。
目前,计算器显示器上显示整数 N。
按加号按钮可将计算器显示屏上显示的当前数字增加1。
同理,按减号按钮可将计算器显示屏上显示的当前数字减1。
计算器不显示任何前导零。
例如,如果计算器显示屏上显示100,则按减号按钮一次将使计算器显示99。
Supervin不喜欢奇数,因为他认为他们是“奇怪的”。
因此,他想通过按动计算器上的按钮来改变显示器上的数字,使得显示数字变为一个全部数位上数字均为偶数的十进制数。
因为计算器比较老旧,按钮并不是很好用,因此Supervin希望尽可能少的按动按钮。
请帮助Supervin确定要使得显示数字各个数位均为偶数,至少需要按动多少次按钮。
输入格式
输入第一行包含整数T,表示共有T组测试数据。
接下来T行,每行包含一个整数N,表示显示器上最初显示的数字。
输出格式
每组测试数据输出一个结果,每个结果占一行。
结果表示为“Case #x: y”,其中x为组别编号(从1开始),y为该组数据结果(即最少按动次数)。
数据范围
1≤T
,
1≤N
输入样例:
4
42
11
1
2018
输出样例:
Case #1: 0
Case #2: 3
Case #3: 1
Case #4: 2
样例解释
在样例#1中,最初显示在计算器上的整数各位均为偶数,因此不需要按下按钮。
在样例#2中,最少按动三次减号按钮使计算器显示8。
在样例#3中,最少按动减号按钮一次使计算器显示0或按动加号按钮一次使计算器显示2。
在样例#4中,最少按动两次加号按钮将使计算器显示2020。
算法:模拟。我们注意到,无论是按“+”还是“-”,两者同时存在的情况下会相互抵消。所以我们只需要考虑只按“+”或只按“-”的时候谁需要的次数更小即可。
当我们按"+"时,我们需要的是找到大于等于当前数的最小偶数,所以在碰到第一个奇数时,后面全置为0;
当我们按“-”时,我们需要的是找到小于等于当前数的最大偶数,所有在碰到第一个奇数时,后面全置为8;
另外需要注意,当奇数为9时,由于“+”需要进位,所以我们在这种情况只需考虑“-”即可。
#include<iostream> #include<algorithm> #include<vector> typedef long long LL; using namespace std; int main(void){ int T; cin>>T; for(int c=0;c<T;c++){ LL n; cin>>n; vector<int>num; LL x=n; while(x)num.push_back(x%10),x/=10; LL l=0,r=0,res=0; for(int i=num.size()-1;i>=0;i--){ int u=num[i]; if(u%2==0){ l=l*10+u; r=r*10+u; } else{ l=l*10+u-1; for(int j=i-1;j>=0;j--)l=l*10+8; res=n-l; if(u!=9){ r=r*10+u+1; for(int j=i-1;j>=0;j--)r=r*10+0; if(res>r-n)res=r-n; } break; } } printf("Case #%d: %lld\n", c+1, res); } return 0; }