題目鏈接:
題意概括:
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