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


    题目描述

    一个双六上面有向前向后无限延续的格子(如下图所示),每个格子都写有整数。其中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;
        }
    
    }
  • 相关阅读:
    可视化数据库管理工具DataGrip使用详解
    MySQL常用函数
    你必须掌握的 21 个 JAVA 核心技术!
    idea中那些好用到飞起的插件
    Object使用
    单页面应用和多页面应用的区别及优缺点
    正则常用匹配
    npm --save-dev 和 --save 的区别
    js常用小技巧
    js复制文字到剪切板
  • 原文地址:https://www.cnblogs.com/LuRenJiang/p/7445684.html
Copyright © 2020-2023  润新知