本题的两个要点在于最大公约数和长整数计算。
1.由于已知某事件在过去发生时刻 ti (1≤i≤N),因此该事件的最大正周期为 GCD(|t2-t1|, |t3-t2|, ..., |tN-t(N-1)|)。其中函数GCD(...)表示最大公约数。若 ti=t(i+1),则不参与计算。
多个数的最大公约数可以通过逐次结合运算求得:
GCD(a, b, c, d) = GCD(GCD(GCD(a,b), c), d)
因此,只要写出求两个正整数最大公约数的方法,就可以求出多个正整数的最大公约数。
以此最大公约数为周期 T ,便可求得该事件下次发生时刻为:(T - ti MOD T) MOD T
2.最大公约数求法,辗转相除法
假设算式 GCD(a,b) 中 a>b,那么使用 a MOD b 代替参数中的 a,可得到相同的结果。GCD(a,b) = GCD(a MOD b, b)
即使用参数中大数除以小数的余数代替大数,然后反复交替相除取余,直到其中一参数为0,即得到答案。
递归代码
function GCD(a, b)
if b = 0
return a
else
return GCD(b, a mod b)
非递归代码
function GCD(a, b)
while b ≠ 0
t := b
b := a mod b
a := t
return a
3.以上 ti 及最大公约数函数的参数 a,b 都是长整数,不能使用普通的四则运算方法,只能自定义一个长整数类,然后重载各种运算操作符。
由于限制了 ti 最大值不超过 10^50,因此可以使用固定长度的结构,而不用设计动态分配内存,可以简化程序。
我的代码中,实现的方法有:
长整数输入(普通整数和字符串转化为长整数)
长整数输出(屏幕输出和长整数转化为字符串)
长整数比较(大于,小于,等于)
长整数加法(加长整数或者短整数)
长整数减法(减长整数或者短整数)
长整数乘法(乘以短整数)
长整数除法(除以长整数)
长整数取模(除以长整数)
此外,长整数除法和取模中需要用到试商函数,其目的为求出商为短整数的两个长整数相除结果,可以使用二分法实现。