CF Gym 100548K Last Denfence(辗转相除法)

                                             Last Denfence

 Last Defence
Description
    Given two integers A and B. Sequence S is defined as follow:
    • S0 = A
    • S1 = B
    • Si = |Si−1 − Si−2| for i ≥ 2
    Count the number of distinct numbers in S.
Input
    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).
Output
    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.
Samples
Sample Input 

  2
  7 4
  3 5

Sample Output
Case #1: 6
Case #2: 5

题意:

这道题是先让你输入两个数A和B,设S0=A,S1=B,然后后面就是S2=S1-S0,SN=S(N-1)-S(N-2);然后要求的就是S这个序列里面有几个不同的数字。

下面把题目中的例子重新列举了一下:

 

思路:

先看这道题的数据A和B都是0~10^18范围内的,所以数据非常大,我之前想用模拟的方法来做,但是做不出来,后来看了网上大佬的博客,明白用辗转相除法来做简化数据,效果很好一下通过了。

首先容易发现,当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。要考虑到其中的A和B有一个为零,或者两个都为零,我做的时候没考虑完整又WA了一次。

代码:

#include<bits/stdc++.h> 
using namespace std;
int main()
{
	long long int a,b,n,ans,tmp;
	cin>>n;//n表示测试的组数 
	for(int i=1;i<=n;i++)
	{
		cout<<"Case #"<<i<<": ";
	  	ans=0;
      	cin>>a>>b;//输入A和B,表示S0和s1, 
	  	if(a==0&&b==0)//当这两个数都等于零的时候,那么序列中不同的数只有一个 
		 	{
				cout<<"1\n";
				continue;
			}
	   	if(a==0||b==0)//当这两个数中只有一个为零的时候,那么序列中不同的数只有两个 
		 	{
			  	cout<<"2\n";
			  	continue;
		  	}
	  	while(b)//辗转相除法, 
	  	{
		  	ans+=a/b;
		  	tmp=b;
		  	b=a%b;
		  	a=tmp;
	  	}
      	cout<<ans+1<<endl;//这个输出结果具体题目还是需要调试 
	}
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值