来源:牛客网:

题目描述

我们把十进制下每一位都是偶数的数字叫做“二数”。
小埃表示自己很聪明,最近他不仅能够从小数到大:2,3,4,5....,也学会了从大数到小:100,99,98...,他想知道从一个数开始数最少的数就得到一个二数。但是聪明的小森已经偷偷在心里算好了小埃会数到哪个二数,请你求出他要数到哪个数吧。
换句话说,给定一个十进制下最多105位的数字,请你求出和这个数字的差的绝对值最小的二数,若答案不唯一,输出最小的那个。
也就是说,给定数字n,求出m,使得abs(n-m)最小且m[i] mod 2 = 0

题解:

算一个构造题
比赛时想到了,但是看错数据范围,发现自己写的不对。。。
n<10^,正常肯定不好做,当然可以写大数加减?但是感觉不是正解
正解是按照题目要求构造
因为数很大用string读取
我们要找离目标数最近的二数,就像从目标数的最高位开始,当遇到不是偶数时,假设该位为x,x时奇数,那么离x最近的二数又两种情况(x+1)000...或者(x-1)888....
为什么是这样?因为x是奇数,要让x变为偶数要么加1,要么减一,如果+1,要让二数距离原数最近,后面就要跟最小的二数,最小的二数就是0,所以时(x+1)0000
-1的情况类似,后面是跟最大的二数
那(x+1)000...和(x-1)888..哪个离目标最近?我将两者相加求平均数可得,x444..正好是他们的中间值,当目标数小于x444时,说明里(x-1)888更近,相反离(x+1)000更近
注:如果x为9的话只能减1,加的话就要进位,会使前一个位的偶数+1变成奇数

代码有详细注释

代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+9;
char s[maxn];
int main()
{
    //ios::sync_with_stdio(false);
    int t;
    cin>>t;
    while(t--)
    {
        string sum;
        scanf("%s",s+1);
        int len=strlen(s+1); 
        int f=0;//记录是否出现偶数情况 
        for(int i=1;i<=len;i++)
        {
            if(!f)
            {
                int w=s[i]-'0';
                if(w%2==0)
                {
                    sum+=s[i];
                    continue;    
                }
                if(w==9)//特判情况 
                {
                    f=1;//已出现奇数
                    sum+='8';
                    continue; 
                }
                bool f2=1;//默认的是离(x-1)888更近 
                for(int j=i+1;j<=len;j++)
                {
                    if(s[j]=='4')continue;
                    if(s[j]<'4')break;
                    if(s[j]>'4')
                    {
                        f2=0;
                        break;
                    } 
                }
                if(f2)
                {
                    sum+=(s[i]-1);
                    f=1;
                }
                else 
                {
                    sum+=(s[i]+1);
                    f=2;
                }
            }
            else 
            {
                if(f==1)sum+='8';//后面根888 
                else sum+='0';//后面根000 
            }
        }
        if(sum[0]=='0'&&sum.size()>1)
        {
            sum.erase(sum.begin());//避免首位是0 
        }
        cout << sum << endl;
    }
 }