zoukankan      html  css  js  c++  java
  • 2015 Benelux Algorithm Programming Contest I- Interesting Integers

    题目大意:给你一个数字n(n<=1e9) ,让你求一个能包含这个数的斐波那契数列的第一项a

    和第二项b,找出b最小的那个。

    帮我复习了一下扩展欧几里得。。。。

    思路:a,b,a+b,a+2b……我们能枚举出50项内,每一项的a和b的数量,然后就是从后往前解

    二元一次方程。 其实以a为第一项,b为第二项的斐波那切数列公式为,a[ i ]=f[ i - 1 ] * x+f[ i ]*y。

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const ll inf=1e18;
    ll fi[46],se[46],n,a,b,ans1,ans2,res1,res2;
    ll exgcd(ll a,ll b,ll &x,ll &y)
    {
        if(b==0)
        {
            x=1; y=0;
            return a;
        }
        else
        {
            ll gcd,t; gcd = exgcd(b,a%b,x,y);
            t=x; x=y; y=t-(a/b)*y;
            return gcd;
        }
    }
    bool work(ll fi,ll se,ll n,int id)
    {
        if(fi>n || se>n) return false;
        ll x,y,gcd=exgcd(fi,se,x,y);
        if(n%gcd!=0) return false;
        ll g=n/gcd;
        x=x*g; y=y*g;
        ll change1=fi/gcd;
        ll change2=se/gcd;
        if(x<1)
        {
            ll cnt=(1-x)/change2;
            x+=cnt*change2;
            y-=cnt*change1;
            if(x<1)
            {
                x+=change2;
                y-=change1;
            }
            if(y<1) return false;
        }
        else if(y<1)
        {
            ll cnt=(1-y)/change1;
            x-=cnt*change2;
            y+=cnt*change1;
            if(y<1)
            {
                x-=change2;
                y+=change1;
            }
            if(x<1) return false;
        }
        if(x<=y)
        {
            ll cnt=(y-x)/(change1+change2);
            x+=cnt*change2;
            y-=cnt*change1;
            if(x>y || y<1)
            {
                x-=change2;
                y+=change1;
            }
        }
        else
        {
            ll cnt=(x-y)/(change1+change2);
            x-=cnt*change2;
            y+=cnt*change1;
            if(x>y)
            {
                x-=change2;
                y+=change1;
            }
            if(x<1 || y<1) return false;
        }
        if(x<1 || y<1 || x>y) return false;
        res1=x; res2=y;
        return true;
    }
    int main()
    {
        ll x,y;
        fi[1]=1;se[1]=0;fi[2]=0;se[2]=1;
        for(int i=3;i<=45;i++)
        {
            fi[i]=fi[i-1]+fi[i-2];
            se[i]=se[i-1]+se[i-2];
        }
        int T; scanf("%d",&T);
        while(T--)
        {
            scanf("%I64d",&n);
            ans1=ans2=inf;
            for(int i=45;i>=1;i--)
            {
                if(work(fi[i],se[i],n,i))
                {
                    if(res2<ans2)
                    {
                        ans2=res2;
                        ans1=res1;
                    }
                    else if(res2==ans2 && res1<ans1)
                    {
                        ans2=res2;
                        ans1=res1;
                    }
                }
            }
            printf("%I64d %I64d
    ",ans1,ans2);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Linux-文件目录管理
    20. 有效的括号
    242. 有效的字母异位词
    387. 字符串中的第一个唯一字符
    136. 只出现一次的数字
    14. 最长公共前缀
    268. 丢失的数字
    169. 多数元素
    26. 删除有序数组中的重复项
    283. 移动零
  • 原文地址:https://www.cnblogs.com/CJLHY/p/7610793.html
Copyright © 2011-2022 走看看