CDOJ 1639 Fruit Ninja

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


你可能感兴趣的:(规律,模运算)