题目链接:
题意概括:
Gabonacci数列类似于斐波那契数列,都满足某位的值是前两位的和
不同点在于该数列前两位 是由我们自定义的。
现在指定一个 , 求最小的 组合,使 是该数列中的某一位。最小的定义是
尽可能小,同时 ,不存在 相同, 不同的情况。
数据范围:
, 测试数据不超过100组
题解思路:
当 , 我们可以列举后面的几位
可以发现,每一位上的 与 的系数各自都满足变形的斐波那契数列
问题简化成求解等式
由于 , 当数列的值达到1e9结束,因此 , 只需要遍历 的所有情况,每种情况可以构造出一个二元一次方程
用扩展欧几里德算法求解不定方程的方法便可。传送门。
注意此题对解有限定(x = a , y = b):
- y 要尽量小
- x y
对一个不定方程而言,x与y的值是互斥的,或者说是当一个增大时,另一个按比例减小。所以,这里实质上就是在求x、y最接近时的解。
代码:
//求x,y最接近的解,x <= y.
bool Indefinite_equation(int a, int b, int n, ll& x, ll& y) {
int gcd = extgcd(a, b, x, y);
if (n % gcd) return false;
int k = n / gcd, dx = b / gcd, dy = a / gcd; //dx,dy分别为对应的变化值
x *= k;
y *= k; //此为某特解
ll cnt = (y - x) / (dx + dy);
if (cnt < 0 && (y - x) % (dx + dy)) cnt --; //处理x > y的情况
x += dx * cnt;
y -= dy * cnt;
return true;
}
具体的证明在另外文章中有说。
这里请注意,参与计算的 x , y 应该开成 long long 型,否则在扩展欧几里德算法求特解时,会溢出。
AC代码:
#include <stdio.h>
using namespace std;
const int MAXN = 46;
typedef long long ll;
int extgcd(int a, int b, ll& x, ll& y) {
int gcd = a;
if (b != 0) {
gcd = extgcd(b, a % b, y, x);
y -= (a / b) * x;
}
else {
x = 1; y = 0;
}
return gcd;
}
//求x,y最接近的解,x <= y.
bool Indefinite_equation(int a, int b, int n, ll& x, ll& y) {
int gcd = extgcd(a, b, x, y);
if (n % gcd) return false;
int k = n / gcd, dx = b / gcd, dy = a / gcd; //dx,dy分别为对应的变化值
x *= k;
y *= k; //此为某特解
ll cnt = (y - x) / (dx + dy);
if (cnt < 0 && (y - x) % (dx + dy)) cnt --; //处理x > y的情况
x += dx * cnt;
y -= dy * cnt;
return true;
}
int main() {
int T;
scanf("%d", &T);
int f[MAXN] = {1, 0};
for (int i = 2; i < MAXN; i++)
f[i] = f[i - 1] +f[i - 2];
while (T --) {
int n;
scanf("%d", &n);
ll tempx, tempy, x = 0, y = 0x3f3f3f3f;
for (int i = 0; i < MAXN - 1; i++) {
Indefinite_equation(f[i], f[i + 1], n, tempx, tempy);
if (tempx > 0 && tempy > 0 && tempy < y) {x = tempx; y = tempy;}
}
printf("%lld %lld\n", x, y);
}
}
Interesting Integers
Undoubtedly you know of the Fibonacci numbers. Starting with F1 = 1 and F2 = 1,every next number is the sum of the two previous ones. This results in the sequence1,1,2,3,5,8,13,⋅⋅⋅.
Now let us consider more generally sequences that obey the same recursion relation
but start with two numbers of our own choice. We shall call these Gabonacci sequences. For example, if one uses = 1 and = 3, one gets what are known as the Lucas numbers: 1, 3, 4, 7, 11, 18, 29, ⋅ ⋅ ⋅ . These numbers are – apart from 1 and 3 – different from the Fibonacci numbers.
By choosing the first two numbers appropriately, you can get any number you like to appear in the Gabonacci sequence. For example, the number n appears in the sequence that starts with 1 and n − 1, but that is a bit lame. It would be more fun to start with numbers that are as small as possible, would you not agree?
Input Format
On the first line one positive number: the number of test cases, at most 100. After that per test case:
one line with a single integer n (): the number to appear in the sequence.
Output Format
Per test case: one line with two integers a and b (0<a≤b), such that,for =a and =b, = n for some k. These numbers should be the smallest possible, i.e., there should be no numbers a′ and b′ with the same property, for which b′ < b, or for which b′ = b and a′ < a.
样例输⼊
5
89
123
1000
1573655
842831057
样例输出
1 1
1 3
2 10
985 1971
2 7