Codeforces Round #667 (Div. 3) 参与排名人数12482
[codeforces 1409D] Decrease the Sum of Digits 取出各个位置上的数+特判+数据进位考虑
总目录详见https://blog.csdn.net/mrcrack/article/details/103564004
在线测评地址http://codeforces.com/contest/1409/problem/D
Problem | Lang | Verdict | Time | Memory |
---|---|---|---|---|
D - Decrease the Sum of Digits | GNU C++17 | Accepted | 46 ms | 0 KB |
题目大意:给出一个数n,取出各个位置上的数求和,若和值大于s,可以进行一次n=n+1的操作,继续取出各个位置上的数求和,若和值大于s,再进行一次n=n+1的操作,继续取出各个位置上的数求和,依次类推,要求操作的次数尽可能小,使其和值小于等于s.
基本思路:取出n各个位置上的数,求和,若和值小于等于s,输出0.若和值大于s,那么请看样例模拟过程。
部分样例模拟如下:
500 4
500
500可分成5,0,0
因5>4,需再找上一位,该问题,找到了千位+1,百位,十位,个位均填充0
故最小n=1000,差值是1000-500=500
AC代码如下:
#include <stdio.h>
#define LL long long
LL n,d;
int a[25],tot,sum;
void i2b(LL x){//取出x各个位置上的数
tot=0,sum=0;
for(int i=1;i<=20;i++)a[i]=0;
while(x){
a[++tot]=x%10;
sum+=a[tot];
x/=10;
}
}
int main(){
int t,s,i,j;
scanf("%d",&t);
while(t--){
scanf("%lld%d",&n,&s);
i2b(n);
if(sum<=s){printf("0\n");continue;}//特判
for(i=tot;i>=1;i--)
if(a[i]<s)s-=a[i],sum-=a[i];
else break;//a[i]>=s
i++;//保证第i位以及比第i位,更高的所有数值之和小于s.
if(i>tot){//i若超越了最高位tot
d=1;
for(j=tot;j>=1;j--)d*=10;
printf("%lld\n",d-n);
}else{//i<=tot
a[i]+=1;//当前位,数值加1
for(j=i;j<=tot;j++){//进位处理
a[j+1]+=a[j]/10;
a[j]%=10;
}
if(a[j])tot++;//考虑数据位数增加的情况。
d=a[tot];
for(j=tot-1;j>=i;j--)d*=10,d+=a[j];
for(j=i-1;j>=1;j--)d*=10;
printf("%lld\n",d-n);
}
}
return 0;
}