【2014acm西安现场赛】K

来源:互联网 发布:软件测试简单吗 编辑:程序博客网 时间:2024/05/17 01:07

题目链接:

https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=5057


题目大意:

给定数列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

#include<bits/stdc++.h>using namespace std;int main(){//  freopen("data.txt","r",stdin); // freopen("out.txt","w",stdout);   int T;  unsigned long long a,b,t,ans;  cin>>T;  for(int i=1;i<=T;i++){    cin>>a>>b;   // cout<<a<<" "<<b<<endl;    printf("Case #%d: ",i);    if (a==b) {        if (a==0) printf("1\n");        else printf("2\n");        continue;    }    ans=2;    if (a<b) swap(a,b);    if (b==0) {printf("2\n");continue;}    while(b!=0){        ans+=a/b;        a%=b;        swap(a,b);    }    cout<<ans-1<<endl;  }  return 0;}


阅读全文
0 0