如何理解" q = i - 4的代码; "在这个答案中?

时间:2017-06-23 11:34:14

标签: c++ algorithm

  

问题说明

     

数字序列定义如下:

f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7.
     

给定A,B和n,你要计算f(n)的值。

     

输入

     

输入包含多个测试用例。每个测试用例在单行上包含3个整数A,B和n(1 <= A,B <= 1000,1 <= n <= 100,000,000)。三个零表示输入结束,并且不处理此测试用例。

     

输出

     

对于每个测试用例,在一行上打印f(n)的值。

示例输入

1 1 3
1 2 10
0 0 0

示例输出

2
5

代码

#include <iostream>
using namespace std;

int f[54] = {0, 1, 1};
int main()
{
    int A, B, n, q = 1;
    while (cin >> A >> B >> n && A && B && n)
    {
        for (int i = 3; i < 54; ++i)
        {
            f[i] = (A * f[i - 1] + B * f[i - 2]) % 7;
            if (i > 4)
            {   
                if (f[i - 1] == f[3] && f[i] == f[4]) //here too
                {
                    q = i - 4; //I can't catch the point
                }
            }
        }
        cout << f[n % q] << endl;

    }
    return 0;
}

2 个答案:

答案 0 :(得分:11)

鉴于f(n)完全由f(n - 1)f(n - 2)确定,且f(x)是0到6之间的整数,因此只有7 * 7 = 49种组合f(n - 1)f(n - 2)。这意味着f(x)是定期的,最长期限为49.一旦我们知道了这段时间,计算f(n)就像f(n % period)一样简单,因为我们计算了f(0)..f(48) 。确切的期限取决于AB,需要进行计算。为了计算周期,我们只需要找到两个连续值f的重复。也就是说,如果f(x) == f(y) && f(x + 1) == f(y + 1),则|y - x|f的句点或其整数倍。请注意,f(n) == f(n % (k*period))的效果与f(n) == f(n % period)相同。因此,在问题q中,代码是f的句号或其整数倍。

现在,为什么代码预先计算f(0)..f(53)而不是f(0)..f(48)?我认为这是一种矫枉过正,因为超出最长期限的两个额外元素就足够了。

有关代码的另一个令人不安的事情是,f[0]是假值,如果nq的倍数,则可能会返回该值。这可能是一个错误。为防止这种情况发生,我会将f的索引编制为一,将f(0) == 1 && f(1) == 1而不是f(1) == 1 && f(2) == 1。{/ p>

答案 1 :(得分:8)

是的,这种问题应该是OnlineJudge(OJ)的一个问题。也许你是ACM的新手?

Blew是我的答案:

解决方案可以解决的原因是因为mod 7,这意味着答案只能是0,1,2,3,4,5,6。所以,这个问题只能从3到54循环,因为足够了。怎么说,因为f [n]只用f [n-1]和f [n-2]之前的两个值确定,f [n-1]有7个选择(0-6)所以f [的n-2]。

所以具有更多49的循环就足够了,当一些f [n-1]和f [n-2]等于f [4]和f [3]时,以下值将循环。

看看你的第二个例子。

f[1] = 1
f[2] = 1
A = 1
B = 2
n = 10 // or set n larger.

我们会得到

f[3] = 3
f[4] = 5
f[5] = 4
f[6] = 0
f[7] = 1
f[8] = 1
f[9] = 3
f[10] = 5
f[11] = 4

作为f[9] == f[3]f[10] == f[4],然后它将在数字4, 0, 1, 1, 3, 5

之后传播

所以q = i - 4删除了前四个数字,因为n%q是循环序列中第n个数字的位置。

我想知道我是否清楚地说明了答案,希望这对你有所帮助。