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

时间:2022-05-25 00:26:52

题意:

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

分析:

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

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

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

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

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

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

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

 #include <cstdio>

 using namespace std;

 const int maxn =  + ;

 char a[maxn], b[maxn];

 bool can(int m, int s)
{
return (s >= && s <= m*);
} int main()
{
int m, s;
scanf("%d%d", &m, &s);
if(!can(m, s))
{
puts("-1 -1");
return ;
} int sum = s, p = ;
for(int i = ; i < m; ++i)
{
for(int d = ; d < ; ++d)
{
if((i > || d > || (m == && d == )) && can(m-i-, sum-d))
{
a[p++] = '' + d;
sum -= d;
break;
}
}
}
if(p != m)
{
puts("-1 -1");
return ;
}
for(int i = ; i < p; ++i) putchar(a[i]);
putchar(' '); sum = s; p = ;
for(int i = ; i < m; ++i)
{
for(int d = ; d >= ; --d)
{
if(can(m-i-, sum-d))
{
b[p++] = '' + d;
sum -= d;
break;
}
}
}
if(p != m)
{
puts("-1 -1");
return ;
}
for(int i = ; i < m; ++i) putchar(b[i]);
puts(""); return ;
}

代码君