NYOJ 875 小M的操作数

小M的操作数

时间限制: 1000 ms  |  内存限制: 65535 KB
难度: 2
描述
最近小M上课老瞌睡,落下许多功课,现在就遇到了一个问题:
当一个数对(x,y)中有一个数大于或等于m时(当然有两个更好了),我们称它为m数对。 一个数对(x,y)可以经过一步操作变成变成(x,x+y)或(x+y,y)数对。 现在计算一个数对(x,y)变成m数对最少的操作次数吗?  你能帮助小M吗,输出最小的操作次数,如果不能变成m数对输出-1。
输入
输入x,y,m,( -10^18 ≤ x , y , m ≤ 10^18 )
输出
输出结果。
样例输入
1  2  5
0 -1  5
样例输出
2
-1


此题是给定(x,y)数对,问至少经过多少次变换能使至少有一个数大于或等于m。

假设x>0,y>0,我们每次用x+y来替换x,y中较小的那个,假设x<y,则第一次操作后变成(x+y,y),第二次操作后变成(x+y,x+2*y)

第三次后变成(2*x+3*y,x+2*y)…………第k次操作后较大的数等于fib[k]*y + fib[k-1]*x,其中fib[ ]是斐波那契数。

对于x,y小于0的,转换成正的即可。


#include<stdio.h>
#include<algorithm>
using namespace std;
typedef long long LL;
LL fib[100];
void get_fib()
{
    fib[0] = 1; fib[1] = 1;
    for(int i = 2; i <= 90; i++)
        fib[i] = fib[i-1] + fib[i-2];
}
int main()
{
    get_fib();
    LL x, y, m;
    while(~scanf("%lld%lld%lld",&x, &y, &m))
    {
        LL temp, i, sum = 0;
        if(x >= m || y >= m)
        {
            printf("0\n");
            continue;
        }
        if(x > y) swap(x,y);
        if(x <= 0 && y <= 0)
        {
            if(y >= m)  printf("0\n");
            else  printf("-1\n");
            continue;
        }
        if(x < 0 && y > 0)
        {
            sum = (-x) / y + 1;
            x += sum * y;
        }//求出把x变成正数需要的次数
        if(x > y) swap(x,y);
        for(i = 1; i <= 90; i++)
        {
            temp = fib[i]*y + fib[i-1]*x;
            if(temp >= m)
                break;
        }
        printf("%lld\n",sum + i);
    }
    return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值