题意: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;
}