Problem A. Even Digits Google Kickstart Round A 2018

题意:given an integer,有add 1和minus 1两种操作,问经过最少几个operation,可以将当前integer变为所有数字(digit)都是偶数的integer。

小数据枚举即可,一种方法是不停地add,另一种是不停地minus。比较两种结果哪一个需要的operation次数最小。

大数据,如果是第一种情况,那么将位数最高的odd digit +1,后面的数全变成零。E.g.,201834 -> 202000, 2018 -> 2020。如果位数最高的odd digit+1=10,模拟进位使得更高一位变成odd的digit再+1变成even。循环直到所有的digit都是even。思路是如果先改变非最高位的digit,可能因为进位退位引发更高为的digit变化。

如果是第二种情况,将位数最高的odd digit-1,后面的数全变成8,因为8是最大的10以内的偶数,这样可以使得与initial integer距离最小。我开始纠结要不要把后面的odd digit+1,但这样会引发进位,可能有使得前面的even digit变成odd了,绕了好久。o(╥﹏╥)o e.g., 201834 -> 200888

之后比较这两种case对应的Operation次数。

#include<iostream>
#include<stdio.h>
#include<cstdio>
#include<string>
#include<cmath>
#include<stdlib.h>
#include<algorithm>
#include<string.h>
#include<cstring>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<windows.h>
using namespace std;

const int maxn=20;
long long N;
int arr[maxn];
int ed;
long long ans;
int tmparr[maxn];
int T;
int higest_odd(int a[], int aed)
{
    int ret=-1;
    for(int i=0;i<aed;i++)
    {
        if(a[i]%2==1)
        {
            ret=i;
        }
    }
    return ret;
}
void print_tmparr()
{
    for(int i=ed;i>=0;i--)
    {
        cout<<tmparr[i];
    }
    cout<<endl;
}
void print_arr()
{
    for(int i=ed;i>=0;i--)
    {
        cout<<arr[i];
    }
    cout<<endl;
}
int find_tmparr_end()
{
    int ret=0;
    for(int i=ed+1;i>=0;i--)
    {
        //cout<<"i "<<i<<" tmparr[i] "<<tmparr[i]<<endl;
        if(tmparr[i]>0)
        {
            ret=i;
            break;
        }
    }
    return ret;
}
long long cal_gap(int a[])
{
    long long ret1=0;
    long long ret2=0;
    for(int i=ed-1;i>=0;i--)
    {
        ret1=ret1*10+arr[i];
    }
    int ed2=find_tmparr_end()+1;
    //cout<<"tmparr ed2 "<<ed2<<endl;
    for(int i=ed2-1;i>=0;i--)
    {
        ret2=ret2*10+a[i];
    }
    //cout<<ret1<<" ret "<<ret2<<endl;
    if(ret1>ret2)
    {
        return ret1-ret2;
    }
    else
    {
        return ret2-ret1;
    }
}
int main()
{
//    freopen("input.txt","r",stdin);

    //freopen("A-large.in","r",stdin);
    freopen("A-small-attempt0.in","r",stdin);
    freopen("Alarge.txt","w",stdout);
    cin>>T;
    for(int ca=1;ca<=T;ca++)
    {
        memset(arr,0,sizeof(arr));
        memset(tmparr,0,sizeof(tmparr));
        ed=0;
        ans=0;
        cin>>N;
        long long tmpN=N;
        int maxed=-1;
        while(tmpN!=0)
        {
            arr[ed]=tmpN%10;
            if(arr[ed]%2==1)
            {
                maxed=ed;
            }
            tmpN=tmpN/10;
            ed++;
        }
        if(maxed==-1)
        {
            ans=0;
            printf("Case #%d: %d\n", ca, ans);
            continue;
        }
        memset(tmparr,0,sizeof(tmparr));
        // add
        //cout<<"add"<<endl;
        for(int i=0;i<maxed;i++)
        {
            tmparr[i]=0;
        }
        tmparr[maxed]=arr[maxed];
        for(int i=maxed+1;i<ed;i++)
        {
            tmparr[i]=arr[i];
        }
        //print_tmparr();
        while(true)
        {
            maxed=higest_odd(tmparr,ed+1);
            //cout<<"maxed "<<maxed<<" tmparr "<<endl;
            //print_tmparr();
            if(maxed==-1)
            {
                break;
            }
            tmparr[maxed]=tmparr[maxed]+1;
            int idx=maxed;
            //cout<<"ed "<<ed<<" idx "<<idx<<endl;
            while(tmparr[idx]==10)
            {
                tmparr[idx]=0;
                idx++;
                tmparr[idx]=tmparr[idx]+1;//the same as using tmparr?
                //print_tmparr();
            }

        }
        //print_tmparr();
        ans=cal_gap(tmparr);
        //sub
        //cout<<"sub"<<endl;
        memset(tmparr,0,sizeof(tmparr));
        maxed=higest_odd(arr,ed);
        tmparr[maxed]=arr[maxed]-1;
        //print_arr();
        //cout<<"maxed "<<maxed<<endl;
        //print_tmparr();
        for(int i=maxed+1;i<ed+1;i++)
        {
            tmparr[i]=arr[i];
        }
        //print_tmparr();
        for(int i=0;i<maxed;i++)
        {
            tmparr[i]=8;
        }
        //print_tmparr();
        ans=min(ans,cal_gap(tmparr));
//        while(true)
//        {
//            maxed=higest_odd(tmparr,ed);
//            if(maxed==-1)
//            {
//                break;
//            }
//            tmparr[maxed]=arr[maxed]+1;
//            int idx=maxed;
//            while(idx<=ed)
//            {
//                if(tmparr[idx]==10)
//                {
//                    tmparr[idx]=0;
//                    idx++;
//                    tmparr[idx]=arr[idx]+1;
//                }
//                else
//                {
//                    idx++;
//                }
//            }
//        }
        printf("Case #%d: %lld\n", ca, ans);

    }
    return 0;
}

暴力的小数据:

#include<iostream>
#include<stdio.h>
#include<cstdio>
#include<string>
#include<cmath>
#include<stdlib.h>
#include<algorithm>
#include<string.h>
#include<cstring>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<windows.h>
using namespace std;

const int maxn=20;
long long N;
int arr[maxn];
int ed;
int ans;
int tmparr[maxn];
int T;
long long upper;
int main()
{
//    freopen("input.txt","r",stdin);

    freopen("A-small-attempt0.in","r",stdin);
    freopen("A.txt","w",stdout);
    cin>>T;
    for(int ca=1;ca<=T;ca++)
    {
        memset(arr,0,sizeof(0));
        ed=0;
        ans=0;
        upper=0;
        cin>>N;
//        while(N!=0)
//        {
//            arr[ed]=N%10;
//            N=N/10;
//        }
//        for(int i=0;i<4;i++)
//        {
//            memset(tmparr,0,sizeof(0));
//            for(int )
//
//        }
        int tmpans = 0;
        for(long long i=N;i<=1e6;i++)
        {
            bool flg=true;
            long long j=i;
            while(j!=0)
            {
                int tmp=j%10;
                j=j/10;
                if(tmp%2==1)
                {
                    flg=false;
                    break;
                }
            }
//            cout<<i<<" "<<flg<<endl;
            if(flg==true)
            {
                tmpans=i-N;
                break;
            }
        }
        ans=tmpans;
        for(long long i=N;i>=0;i--)
        {
            bool flg=true;
            long long j=i;
            while(j!=0)
            {
                int tmp=j%10;
                j=j/10;
                if(tmp%2==1)
                {
                    flg=false;
                    break;
                }
            }
//            cout<<i<<" after "<<flg<<endl;
            if(flg==true)
            {
                tmpans=N-i;
                break;
            }
        }
        ans=min(ans,tmpans);
        printf("Case #%d: %d\n", ca, ans);

    }
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值