对于这个题我只想说呵呵啊,其实这个题在集训的时候就遇到过,当然,我没做出来,今天绝对正面迎击。因为学长说过,这么大的数,连数组都开不出来肯定是需要找规律的,所以我就把各种输入打印前100位找规律,然后无果,决定写一个找循环节的组件然后就写了这样的程序
#include <stdio.h>
int main()
{
int A,B,i,cm;
long long n;
int a[50] = {1,1};
int *p1,*p2;
while (scanf ("%d%d%lld",&A,&B,&n),A || B || n)
{
for (i = 2; i < 50; i++)
{
a[i] = a[i - 1] * A + a[i - 2] * B;
a[i] %= 7;
}
p2 = &a[1];
int ma = 0; //longest B
while (p2 <= &a[49])
{
p1 = a;
cm = 0;
if(*p1 == *p2)
{
int *tp2 = p2;
while (tp2 <= &a[49] && *p1 == *tp2)
{
cm++;
p1++;
tp2++;
}
if (cm > ma)
ma = cm;
}
p2++;
}
ma = 50 - ma;
n %= ma;
printf ("%d\n",a[n - 1]);
}
return 0;
}
自己测试了数据然后交上去WA了,然后不甘心,于是在网上百度了段代码,运行出来然后用自己的测试数据一个一个比较,居然发现有一个不一样的= =
在前两项相同的情况下居然有不一样的数据。
果断震惊啊,难度是我循环节找错了?应该就是这里的问题,不过看到网上人的分析,感觉有些道理,因为每个成员都是%7过的,所以都是0-6七种可能,那么下一项是前两项决定的,那么会有7 * 7 = 49种可能,那么,最多就是49次一循环,然后看到他居然是%48,感觉各种震惊,如果我这循环嵌套就是找到也很费时间的说。
然后按照他的思路,就这样改了代码
#include <stdio.h>
int main()
{
int A,B,i;
long long n;
int a[50] = {1,1};
while (scanf ("%d%d%lld",&A,&B,&n),A || B || n)
{
for (i = 2; i < 50; i++)
{
a[i] = a[i - 1] * A + a[i - 2] * B;
a[i] %= 7;
}
n %= 48;
printf ("%d\n",a[n - 1]);
}
return 0;
}