Educational Codeforces Round 90 (Rated for Div. 2) - E. Sum of Digits

题意:

给定 \(n\)\(k~(1 \leq n \leq 150,0 \leq k \leq 9)\) ,找到最小的 \(x\) ,使得:

\[f(x)+f(x+1)+ \cdots + f(x+k)=n \]

其中 \(f(x)\) 表示 \(x\) 的十进制数字的和

分析:

因为 \(0 \leq k \leq 9\) ,所以最多会产生一次进位,

Ⅰ:

首先考虑没有进位的情况,那么容易想到枚举 \(x\) 个位数上的数,求出 \(x\)\(x+k\) 个位数的和 \(sum\),然后判断 \(if((n-sum)\%(k+1)==0)\) 对应有没有解;

Ⅱ:

然后考虑有进位的情况,事先需要明确一点,因为是求最小值,所以除了个位数,是不会存在 \(9+1\) 进位的,因为产生一个 \(9+1\) 进位就等价于十进制数和减少了 \(8\) ,得不尝试;所以个位数产生进位的情况下 十位数上最大为 \(8\)

代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define frep(i,a,b) for(int i=a;i>=b;i--)
int n,k;
int sum[10][10];  //sum[i][j],表示 i~j 的和


void init()
{
	rep(i,0,9)rep(j,0,9){
		int a=0;
		if(i<=j) rep(z,i,j) a+=z;
		else{
			rep(z,i,9) a+=z;
			rep(z,1,j) a+=z;
		} 
		sum[i][j]=a;
	}
}

int main()
{
	//freopen("1.txt","r",stdin);
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	
	init();
	
	int t;
	cin>>t;
	while(t--)
	{
		vector<string>ANS;
	    cin>>n>>k;
	
	    rep(start,0,9)
	    {
	    	int end=(k+start)%10;
	    	
	    	int num=sum[start][end];
	    	if(num>n) continue;  //个位数的和就大于n,肯定无解
	    	if(num==n&&start<=end)  //最简单的解
	    	{
	    		string s;
	    		s+=(start+'0');
	    		ANS.pb(s);
	    		continue;
			}
			
			int m=n-num,cnt=0;
			if(start>end) cnt=end+1;
			// m 表示除开个位数的和
			// cnt 表示进位的数的个数
			
			if(cnt==0)  //没有产生进位
			{
				if(m%(k+1)!=0) continue;
				string s;
				s+=(start+'0');
				m/=(k+1);
				
				int tim=m/9;
				while(tim--) s+='9';
				if(m%9>0) s+=(m%9)+'0';  
				//从十位数位往上填,没有进位,肯定尽量填9,以此满足x最小的要求
				
				reverse(s.begin(),s.end());
				ANS.pb(s); 
			}
			
			else if(m>=cnt)  //有进位的情况,进位的数的十位数位都加1,所以得比较
			{
				if((m-cnt)%(k+1)==0)
				{
					int lft=m-cnt;
					lft/=(k+1);
					string s;
					s+=(start+'0');
					if(lft>0) //因为个位数有进位,十位数位上最多填8
					{
					    if(lft<=8) s+=(lft+'0'),lft=0;
					    else  s+='8',lft-=8;	
					}
					
					int tim=lft/9;
				    while(tim--) s+='9';
				    if(lft%9>0) s+=(lft%9)+'0';
				    
					reverse(s.begin(),s.end());
				    ANS.pb(s);
				}		
			}
		
		}
		if(ANS.size()==0) cout<<-1<<endl;
		else{
			int ML=1e9;
			for(string s:ANS) ML=min(ML,(int)s.length());  //先找到最小解的长度
			vector<string>Ne;
			for(string s:ANS) if(s.length()==ML) Ne.pb(s);
			sort(Ne.begin(),Ne.end()); 
			cout<<Ne[0]<<endl;
		}
	}
} 

猜你喜欢

转载自www.cnblogs.com/17134h/p/13198882.html