zoj3336 模拟

Friend Number II

Time Limit: 1 Second Memory Limit: 32768 KB

Given a positive integer x, let S(x) denotes the sum of all x's digits. Two integers x and y are friend numbers if S(x)=S(y). Here comes the problem: Given a positive integer x, of course it has a lot of friend numbers, find the smallest one which is greater than x,please.

Input

There are multiple test cases. The first line of input is an integer T (0<T<230) indicating the number of test cases. Then T test cases follow. Each case is an integer x (0<x<=101000).

Output

For each test case, output the result integer in a single line.

Sample Input

3
12
19
222

Sample Output

21
28
231

题意:给出一个数x,要找到一个各位数之和与x相等,且是比它大中最小的数

思路:其实很容易就能发现,只要从后往前边累加边找,当找到某一位不为9且这一位后面那些数的和不为0便可以开始处理。

首先,把该位+1存到另一个字符串中,然后从最后一位开始处理,当和大于9时,依次往前补9,补到和小于9时,剩下那位就补剩下的和,接着从这位开始到刚才+1的那一位之间补0。这样就保证一定最优。剩下+1那一位前面的那一段直接原封不动地保留下来。

例如:871299300 ,3虽不等于9但后面和为0,无法直接处理。直到找到2不等于9,且后面99300又不等于0。所以2变成3,99300和为12,从后往前补两个9,再补3,再补0,就是300399,然后前面保留下来,最终答案就是871300399

注意全部为9的情况就好了

#include<cstdio>
#include<cstring>
char fu[1250];
char zi[1250]={0};
int tp;

int main(void){
	int t,sum,len,ok;
	scanf("%d",&t);
	while(t--){
		scanf("%s",fu);
		len=strlen(fu);
		tp=1200;
		sum=ok=0;
		for(int i=len-1;i>=0;i--,tp--){
			if(ok) {
				zi[tp]=fu[i];
				continue;
			}
			sum+=fu[i]-'0';
			if(fu[i]=='9'||sum-(fu[i]-'0')==0) continue;
			else {
				zi[tp]=fu[i]+1;
				sum-=zi[tp]-'0';
				int now=1200;
				while(sum/9){
					zi[now--]='9';
					sum-=9;				
				}
				if(sum) zi[now--]=sum+'0';
				for(;now>tp;now--)
					zi[now]='0';
				ok=1;
			}
		}
		if(ok==0){
			zi[tp]='1';
			sum--;
			int now=1200;
			while(sum/9){
				zi[now--]='9';
				sum-=9;				
			}
			if(sum) zi[now--]=sum+'0';
			for(;now>tp;now--)
				zi[now]='0';
			tp--;
		}
		printf("%s\n",&zi[tp+1]);
	}
	return 0;
}




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值