• Educational Codeforces Round 90 (Rated for Div. 2)


    题意:

    给定 (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;
    		}
    	}
    } 
    
  • 相关阅读:
    线性代数:矩阵行列式
    线性代数:逆变换
    线性代数:线性变换
    线性代数:零空间
    线性代数:向量乘法
    线性代数基础:向量组合
    线性代基础理论:向量
    线性代基础理论:矩阵
    SpringBoot 消费NSQ消息
    将Oracle中的数据放入elasticsearch
  • 原文地址:https://www.cnblogs.com/17134h/p/13198882.html
Copyright © 2020-2023  润新知