首页 > 代码库 > nefu 630 Min Chain

nefu 630 Min Chain

题目:大意是说给定两个数,让你用这两个数,随意地进行+或者-两种操作,求出最小操作数使得结果为1,当不可能达到1的时候,输出-1.

方法:明显的数论题目,相当于求出ax+by=1的解。

           当两个数不互素时,得不到1的结果;

           当两个数互素时,使用拓展欧几里德来求得x和y,输出abs(x)+abs(y)-1即可。

注意:这道题目的数据涉及0、1,这些数据需要单独处理。

代码:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;

long long gcd(long long a,long long b)
{
    long long r=a%b;
    while(r)
    {
        a=b;
        b=r;
        r=a%b;
    }
    return b;
}

void exgcd(long long m,long long n,long long  &x,long long &y)
{
    if(n==0)
    {
        x=1;
        y=0;
        return;
    }
    else exgcd(n,m%n,x,y);
    long long t=x;
    x=y;
    y=t-m/n*y;
}
int main()
{
    long long da,db;
    long long n;
    cin>>n;
    while(n--)
    {
        cin>>da>>db;
        if(da==0&&db==0||da==0&&db!=1||db==0&&da!=1)
        {
            cout<<-1<<endl;
            continue;
        }
        if(da==0&&db==1||db==0&&da==1)
        {
             cout<<1<<endl;
             continue;
        }
        if(da==1||db==1)
        {
            if(da==2||db==2)
                cout<<1<<endl;
            else
            cout<<2<<endl;
            continue;
        }
        long long r=gcd(da,db);
        if(r!=1) printf("-1\n");
        else
        {
            long long X,Y;
            exgcd(da,db,X,Y);
            if(X<0) X=-X;
            if(Y<0) Y=-Y;
            printf("%lld\n",X+Y-1);
        }
    }
    return 0;
}