Problem:http://www.acm.uestc.edu.cn/problem.php?pid=1639
乍一看觉得挺麻烦,但事实上要考虑的特殊情况并不多。
首先从INF的情况入手比较容易,当m为10的倍数时,可以无穷地加下去,例如选10000开始。当m以5为个位时,差不多也是可以无限加,但是有限制。例如加到达55555时,需要额外加一个n,这可能会导致结果不再是5的倍数。但若n是5的倍数,则不会出现这种问题。当n不是5的倍数时,可以对m分别讨论。可能卡住的点出现在55555,555555,5555555。。
设初始分数为a*5,则当a*5+k*m = 55555等时会被卡住,即a+k*(m/5) = 11111等。通过选择a可以让分数尽量避免卡在较小的数上。
m = 5时,必定卡在55555上,结果为止55555+m+n,当时没再加m说就直接错了。。
m = 15,m/5=3,可以考虑11111等数模3的情况,结果是2,0,1,2,0,1。。我们可以合理选择a避开余2和0的情况,这时会卡在1对应的1111111上,因此结果是5555555+m+n
m = 25,m/5=5,11111等对其取模都是1,因此完全可以避过所有的数,结果为INF 。。。
特殊情况考虑完毕后,最大情况是max(9999+n+((9999+n)%5?0:m), 10000+m)。
#include <cstdio>
typedef long long ll;
int main()
{
int T, n, m;
scanf("%d", &T);
for(int ca=0; ca<T; ++ca)
{
scanf("%d%d", &m, &n);
if((m % 10) == 0)
printf("Case #%d: INF\n", ca+1);
else if((m % 5) == 0)
{
if((n % 5) == 0)
printf("Case #%d: INF\n", ca+1);
else
{
printf("Case #%d: ", ca+1);
switch(m)
{
case 5: printf("%lld", (ll)55555+(ll)(n+m)); break;
case 15: printf("%lld", (ll)5555555+(ll)(n+m)); break;
case 25: printf("INF"); break;
case 35: printf("INF"); break;
case 45: printf("%lld", (ll)5555555555555+(ll)(n+m)); break;
}
printf("\n");
}
}
else
{
int max = 9999+n;
if(max % 5 == 0)
max += m;
if(10000+m > max)
max = 10000+m;
printf("Case #%d: %d\n", ca+1, max);
}
}
return 0;
}