zoukankan      html  css  js  c++  java
  • 【扩展欧几里德算法】双六

    题目描述

    一个双六上面有向前向后无限延续的格子(如下图所示),每个格子都写有整数。其中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;
        }
    
    }
  • 相关阅读:
    软件工程双人项目代码规范
    《单元测试之道Java版》读后感
    《凌波微步:软件开发警戒案例集》读后感
    第一次博客作业
    认识Python
    认识JDK和JVM
    C-结构体
    C-字符串和除法
    C-指针和malloc函数
    求一个字符串没有重复字符的最大子串长度
  • 原文地址:https://www.cnblogs.com/LuRenJiang/p/7445684.html
Copyright © 2011-2022 走看看