• 【扩展欧几里德算法】双六


    题目描述

    一个双六上面有向前向后无限延续的格子(如下图所示),每个格子都写有整数。其中0号格子是起点,1 号格子是终点。而骰子上只有a,b,-a,-b四个整数,所以根据a和b的值的不同,有可能无法到达终点。现在的问题是掷出a,b,-a,-b各多少次可以达到终点呢?(双六是类似大富翁的一款桌上游戏,不懂也没关系的啦)

    输入

    一行,包含两个数 a 和 b,两数之间用一个空格分隔,含义如题目所述。

    输出

    一个数,表示掷出四个整数次数的和,如果解不唯一,就输出和最小的值,如果无解则输出 0 。

    样例输入

    4 11

    样例输出

    4

    说明

     数据范围:1≤a,b≤10的9次方。

    样例解释:掷出a为3次,b为0次,-a为0次,-b为1次, 3*a-l*b=l。

     分析

    列个方程,ax1+(-a)x2+bx3+(-b)x4=1,即a(x1-x2)+b(x3-x4)=1,设x1-x2为x,x3-x4为y,则原式=ax+by=1为不定方程,所以用扩展欧几里德算法来求。因为a和-a,b和-b是相互抵消的,所以x取绝对值就是a和-a最小的移动的步数,y同理。

    参考代码

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    using namespace std;
    int extgcd(int a,int b,int& x,int& y);
    int main()
    {
        int a,b;
        int x,y;
        scanf("%d%d",&a,&b);
        if(a<b){
            swap(a,b);
        }
    
       if(extgcd(a,b,x,y)==1){
        if(x<0)x=-x;
        if(y<0)y=-y;
        printf("%d
    ",x+y);
       }
       else
        printf("0
    ");
    
        return 0;
    }
    int extgcd(int a,int b,int& x,int& y){
        if(b==0){
            x=1;
            y=0;
            return a;
        }
        else{
        int t=extgcd(b,a%b,y,x);
        y-=(a/b)*x;
        return t;
        }
    
    }
  • 相关阅读:
    用 Web 实现一个简易的音频编辑器
    TypeScript教程
    他的独,殇情沉醉
    重新拎一遍js的正则表达式
    网络流
    Xmind最新的安装与破解教程
    adb的端口号5037被占用的解决方法
    使用Fiddler模拟弱网测试教程
    web的前台、后台、前端、后端
    常见面试笔试题
  • 原文地址:https://www.cnblogs.com/LuRenJiang/p/7445684.html
Copyright © 2020-2023  润新知