题意:给你T个例子 然后每个例子两个数a 和 b 分别是s1 s2
然后有一个规则 si = 前两个si差的绝对值 (显然i >= 2)
输出不同si值的个数
列个样例 7 2 即继续 5 3 2 1 1 0 1 1 0 1 0 1 0
结论1:首先可以发现到0 之后 基本就会一直循环下去了 知道了结束条件
那一开始就想 模拟 放set 最后统计set个数 不就好了
然后a b 范围是【0,1e18】
再想到了 一个极端的例子 1 1e18 那写下去不就是 (1e18 - 1) 1 (1e18 - 2) (1e18 - 3) 1 。。。。。
起码1e18 + 1个数 次 而1s跑 1e8 题目3s 肯定爆炸
我们以 7 4 为样例 7 4 3 1 2 1 1 0
蓝色是减去的
可以发现 减去的4的个数有1个 3个数有1个 1个数是2个
即7/4 = 1个 4/3 = 1个 3/1 = 3个
7 - 4 = 3 4-3 = 1 3-1=2 3-1-1= 1 3-1-1-1=0
发现了什么3 1 2 0 就是我们要的那些数 怎么求个数也已经知道了 就是 a / b 然后就取模 继续操作
不太对 刚刚说1个的个数 是2个
为什么这样 因为 最后必定会出现一组 数 - num1 = num2 而num1 == num2 这就重复了 如上面的2-1=1
所以先记住 会重复一个 res--
一开始不是还有a b两个数吗 所以要加上
特殊:如果a b 只有一个0 ans = 2个 (0和另一个不是0的数)
若0 0 ans = 1个(即只有0)
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
long long solve(long long a, long long b){
if (b == 0)
return 0;
long long ans = 0;
ans += a / b + solve(b, a%b);
return ans;
}
int main(){
int t;
scanf("%d", &t);
for (int cas = 1; cas <= t; ++cas){
long long a, b;
scanf("%lld%lld", &a, &b);
if (a == 0 && b || a && b == 0){
printf("Case #%d: 2\n", cas);
continue;
}
long long res = solve(max(a, b), min(a, b));
res--;
res += 2;
printf("Case #%d: %lld\n", cas, res);
}
return 0;
}