Last Defence
时间限制:
1000 ms | 内存限制:
65535 KB
难度:
2
-
描述
-
Given two integers A and B. Sequence S is defined as follow:• S0 = A• S1 = B• Si = |Si-1 - Si-2| for i ≥ 2Count the number of distinct numbers in S .
-
输入
-
The first line of the input gives the number of test cases, T. T test cases follow. T is about 100000.
Each test case consists of one line - two space-separated integers A, B. (0 ≤ A, B ≤ 10^18).
输出
- For each test case, output one line containing “Case #x: y”, where x is the test case number (starting from 1) and y is the number of distinct numbers in S . 样例输入
-
2 7 4 3 5
样例输出
-
Case #1: 6 Case #2: 5
-
题目大意:
给定数列S的首两项,要求之后的各项满足Si= |Si−1 − Si−2|(前两项差值的绝对值)。问整个数列S中不同的数字个数。
解题思路:
首先容易发现,当i足够大时,最后一定会出现“xx0xx0...”这样的重复。所以不同数字个数一定是有限的。
究其原因,对于数y和x,y一定能写成kx+b的形式,在数列的生成过程中,会出现kx+b、x、(k-1)x+b、(k-2)x+b、x、...、2x+b、x、x+b、b、x,其中出现的不同数字个数就是(kx+b)/ x,之后问题变成了数x和b的问题,最后可以发现这就是一个辗转相除法的过程。每做一次辗转相除gcd(x,y),不同数字个数就多了x/ y。最后加上一个末尾出现的0。
还有一些特殊情况需要考虑,比如有数字是0。
-
#include<stdio.h> #include<iostream> using namespace std; long long int n,m,ni; long long int we(long long int a,long long int b) { long long int sum=0; while(b) { long long t = b; sum += a / b; b = a % b; a = t; } return sum+1; } int main() { ios::sync_with_stdio(false); int t; scanf("%d",&t); long long int g=0; while(t--) { g++; scanf("%lld%lld",&n,&m); if(n==0&&m==0) { ni=1; } else if(n==0||m==0) { ni=2; } else { ni=we(n,m); } printf("Case #%lld: ",g); printf("%lld\n",ni); } }
-
The first line of the input gives the number of test cases, T. T test cases follow. T is about 100000.