CodeForces 489C (贪心) Given Length and Sum of Digits...

题意:

找出m位且各个数位数字之和为s的最大和最小整数,不包括前导0(比如说003是非法的),但0是可以的。

分析:

这题是用贪心来做的,同样是m位数,前面的数字越大这个数就越大。

所以写一个can(int m, int s)函数,来判断是否存在一个m位数其各位数字之和为s

这里先不考虑前导0的事,代码看起来可能是这个样子的:

bool can(int m, int s)
{
    return (s >= 0 && s <= m*9);
}

比如我们现在要求满足要求的最小整数,从最左边的数开始从0到9开始试,如果后面的数能够构成m-1位和为s-d的数,就开始尝试下一位。

注意:在这里就要加上不能有前导0的判定条件。

求最大数也是类似的,而且还不用考虑前导0.

 1 #include <cstdio>
 2 
 3 
 4 using namespace std;
 5 
 6 const int maxn = 100 + 10;
 7 
 8 char a[maxn], b[maxn];
 9 
10 bool can(int m, int s)
11 {
12     return (s >= 0 && s <= m*9);
13 }
14 
15 int main()
16 {
17     int m, s;
18     scanf("%d%d", &m, &s);
19     if(!can(m, s))
20     {
21         puts("-1 -1");
22         return 0;
23     }
24 
25     int sum = s, p = 0;
26     for(int i = 0; i < m; ++i)
27     {
28         for(int d = 0; d < 10; ++d)
29         {
30             if((i > 0 || d > 0 || (m == 1 && d == 0)) && can(m-i-1, sum-d))
31             {
32                 a[p++] = '0' + d;
33                 sum -= d;
34                 break;
35             }
36         }
37     }
38     if(p != m)
39     {
40         puts("-1 -1");
41         return 0;
42     }
43     for(int i = 0; i < p; ++i) putchar(a[i]);
44     putchar(' ');
45 
46     sum = s; p = 0;
47     for(int i = 0; i < m; ++i)
48     {
49         for(int d = 9; d >= 0; --d)
50         {
51             if(can(m-i-1, sum-d))
52             {
53                 b[p++] = '0' + d;
54                 sum -= d;
55                 break;
56             }
57         }
58     }
59     if(p != m)
60     {
61         puts("-1 -1");
62         return 0;
63     }
64     for(int i = 0; i < m; ++i) putchar(b[i]);
65     puts("");
66 
67     return 0;
68 }
代码君
原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/4105548.html