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; }