acm之旅之扩展欧几里得_拓展欧几里得acm-程序员宅基地

技术标签: ACM  


参考博文: 数论:欧几里得与扩展欧几里得算法
参考博文: 当我真正理解了扩展欧几里得定理

扩展欧几里得方法:
大概思路 :

  • 第一步 : 给出方程 ax + by = c 。 (或ax = c(mod b))。
  • 第二步 : 算出辗转相除法 gcd(a, b) 。
  • 第三步 : 运用扩展欧几里德 ex_gcd(a, b)-> ax + by = gcd(a,b) 的 一组解(x, y)。(实际上,可以使用exgcd一起算出gcd(a, b),省去了第二步)。
  • 第三步: 根据 c % gcd(a, b) 判断是否 ax + by = c 有解 。
  • 第四步 : 根据 ax + by = c 的通解公式 x1 = (x + k * ( b / gcd(a, b) )) * (c / gcd(a, b) 令 b1 = b / gcd(a, b) , 所以 x1 的 最小正整数解 为 : x1 = (x1 % b1 + b1) % b1, 对应的 y1 = (c - a*x1) / b。
青蛙约会

题目链接:青蛙约会
参考博文:挑战程序设计竞赛:青蛙的约会
重点掌握扩展欧几里得的转换和求解方法。
主要问题:

  • 求解x和y。方法
  • 判断是否存在该条件。
The Balance

题目链接:The Balance
一个扩展欧几里得题目,目标在于x和y之和要小,这需要保证重量小的砝码取值尽可能少,以至于趋近与0,所以我们必须从一开始就确定哪一方的单个砝码重量小。具体参考博文当我真正理解了扩展欧几里得定理

代码:

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

typedef long long LL;
LL a, b, d, x, y, p, q, cntx, cnty;

LL extgcd(LL a, LL b, LL &x, LL &y)
{
    
    LL d = a;
    if(b!=0)
    {
    
        d = extgcd(b, a%b, y, x);
        y -= (a/b)*x;
    }
    else
    {
    
        x = 1, y = 0;
    }
    return d;
}

int main()
{
    
    while(scanf("%lld%lld%lld", &a, &b, &d)!=EOF && (a+b+d))
    {
    
        int flag = 0;

        //保证a一定大于b方便下面取值
        if(a<b)
        {
    
            flag = 1;
            swap(a, b);
        }
        
        //x和y的正负值只表示在天平的哪一方
        LL u = extgcd(a, b, x, y);
        x = x*d/u, y = y*d/u;

        LL Min = 1<<29, t;
        //尽可能减少重量小的砝码的数量
        t = y*u/a;

        for(LL i=t-5; i<=t+5; i++)
        {
    
            p = abs(x+(b/u)*i);
            q = abs(y-(a/u)*i);
           
            if(p+q<Min)
            {
    
                cntx = p;
                cnty = q;
                Min = p+q;
            }
        }
        if(!flag)
            printf("%lld %lld\n", cntx, cnty);
        else
            printf("%lld %lld\n", cnty, cntx);
    }
    return 0;
}
Strange Way to Express Integers

题目链接:Strange Way to Express Integers
中国剩余定理的模板题,即求c%a1=r1、c%a2=r2、c%a3=r3等多个式子中的c值,其中ai和ri给出。

  • 思路:可以将c作为桥梁,得到a1 × \times ×X+r1=a2 × \times ×Y+r2,即a1 × \times ×X-a2 × \times ×Y=r2-r1,可以将Y=-Y带入(最后求出Y时取反即可),得到a1 × \times ×X+a2 × \times ×Y=r2-r1,这是一个标准的扩展欧几里得公式,a=a1,b=a2,c=r2-r1。
    本题的重点在于联立多个式子。假定我们已经求出第一个式子的解,对于a1 × \times ×X+r1=a2 × \times ×Y+r2,已经得出X和Y的值,即可以求出c1=a1 × \times ×X+r1。接下来需要做的是把这两个式子转化为一个式子。即c2%lcm(a1,a2)=c,lcm(a1,a2)是a1和a2的最小公倍数,可以理解为新的答案c2即要mod a1,又要mod a2,所以就mod lcm(a1,ba)。而余数c 是刚前面求得的答案,也就是说c1不管怎么折腾,都还会保留一个c,即c2%a1=c%a1=b1,可知没有改变之前的情况。
    所以更新的情况为r1 = a × \times ×X+r1,a=a × \times ×b/d,(d是a和b的最大公约数),然后b = a3, c = r2-r1。

代码:

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

typedef __int64 LL;//与long long 一样
LL k, a, r1, b, r2, c, x, y;

LL extgcd(LL a, LL b, LL &x, LL &y)
{
    
    LL d = a;
    if(b!=0)
    {
    
        d = extgcd(b, a%b, y, x);
        y -= (a/b)*x;
    }else{
    
        x = 1, y = 0;
    }
    return d;
}

int main()
{
    
    while(scanf("%I64d", &k)!=EOF)
    {
    
        int flag = 0;
        scanf("%I64d%I64d", &a, &r1);
        if(k==1)
        {
    
            printf("%I64d\n", a+r1);
            continue;
        }
        for(int i=1; i<k; i++)
        {
    
            scanf("%I64d%I64d", &b, &r2);
            if(flag) continue;
            c = r2-r1;

            LL d = extgcd(a, b, x, y);

            if(c%d)
            {
    
                flag = 1;
                continue;
            }
            //根据c值调整x,y解的大小
            x = x*c/d;
            LL t = b/d;
            x = (x%t+t)%t;//获取最小正整数解
            /*
            采用这种方法会溢出,推荐上面的方法
            LL t = -(d/b)*x;
            x = x+t*b/d;
            if(x<0) x += b/d;*/
            r1 = x*a+r1; a = (a*b)/d;
        }
        if(flag)
            printf("-1\n");
        else
            printf("%I64d\n", r1);
    }
    return 0;
}
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Accept1234/article/details/94359603

智能推荐

Exception in thread “main“ java.lang.IllegalArgumentException:解决方案_exception in thread "main" java.lang.illegalargume-程序员宅基地

文章浏览阅读4.3w次,点赞3次,收藏8次。Exception in thread "main" java.lang.IllegalArgumentException: Comparison method violates its general contract!解决方法_exception in thread "main" java.lang.illegalargumentexception

Spring常见面试题总结(超详细回答)_spring面试题-程序员宅基地

文章浏览阅读10w+次,点赞2.2k次,收藏1.4w次。1、Spring是什么?Spring是一个轻量级的IoC和AOP容器框架。是为Java应用程序提供基础性服务的一套框架,目的是用于简化企业应用程序的开发,它使得开发者只需要关心业务需求。常见的配置方式有三种:基于XML的配置、基于注解的配置、基于Java的配置。主要由以下几个模块组成:Spring Core:核心类库,提供IOC服务;Spring Context:提..._spring面试题

maven多模块 统一版本管理 的正确姿势 (CI Friendly Versions) - ${revision}_reports that usage of properties in modules parent-程序员宅基地

文章浏览阅读1.6w次,点赞3次,收藏21次。在使用Maven多模块结构工程时,配置版本是一个比较头疼的事。继承版本,依赖版本,自身版本,都需要单独定义,很是麻烦。版本号变更使用mvn versions:set,有时候也可能导致版本号不一致、不便于统一管理:mvn versions:set但其实Maven已经提供了这种CI版本的管理方式,下面来介绍具体用法。从Maven 3.5.0-beta-1版本开始,就可以使用${revision},${sha1}和${changelist}作为占位符来替换pom文件了。注意:Id..._reports that usage of properties in modules parent definition is prohibited

电子商城实录------项目目录的结构搭建及其说明3_网上购物系统项目目录结构-程序员宅基地

文章浏览阅读313次。结合上几个章节,我开始对《电子商城实录------项目目录的结构搭建及其说明2》中方法优化Framework.class.php代码加入static:&lt;?php//核心启动类class Framework{public static function run(){echo "hello,wrold!";}//初始化方法private static function ..._网上购物系统项目目录结构

HTML5期末大作业 精彩在线影视网站设计——在线影视(1页) HTML+CSS+JavaScript 学生DW网页设计作业成品 web课程设计网页规划与设计 计算机毕设网页设计源码_dw影视网站源码-程序员宅基地

文章浏览阅读516次。HTML5期末大作业 精彩在线影视网站设计——在线影视(1页) HTML+CSS+JavaScript 学生DW网页设计作业成品 web课程设计网页规划与设计 计算机毕设网页设计源码常见网页设计作业题材有 个人、 美食、 公司、 学校、 旅游、 电商、 宠物、 电器、 茶叶、 家居、 酒店、 舞蹈、 动漫、 明星、 服装、 体育、 化妆品、 物流、 环保、 书籍、 婚纱、 军事、 游戏、 节日、 戒烟、 电影、 摄影、 文化、 家乡、 鲜花、 礼品、 汽车、 其他 等网页设计题目, A+水平作业_dw影视网站源码

cv_bridge与opencv版本不一致导致程序编译错误及无法运行程序问题的解决方案(附带ORB_SLAM3案例))_sh_cv_bridge版本-程序员宅基地

文章浏览阅读3.7k次,点赞7次,收藏40次。目录1、问题描述开发环境我的程序配置2、问题造成的后果3、解决方案说明:4、实例,针对ORB_SLAM3问题5、其他参考解决方案6、另一个例程7、其他:修改系统默认链接的cv_bridge版本号,以及查看当前系统链接的cv_bridge版本号与位置与本篇问题相关的一个问题,可参考我之前的一篇博客:cv_bridge与python版本问题导致编译错误error: return-statement with no value, in function retur._sh_cv_bridge版本

随便推点

项目笔记(一)_如何做项目笔记图片-程序员宅基地

文章浏览阅读561次。有关于使用matlab进行基础的文件读入输出,字符串处理_如何做项目笔记图片

C/C++编程:long long类型_longlong c-程序员宅基地

文章浏览阅读1.2w次,点赞3次,收藏7次。数据类型long long是C++11中重新定义的,标准规定它最小是64bit在这之前为了提供超过32bit的整数,各个开发环境(编译器)分别定义了各自的64bit整数类型。这会导致代码不兼容现在,C++11直接定义了long long类型我猜许多人应该使用过这个类型,当然在C++11之前,这种尝试会被编译器无情拒绝,自C++11之后就不会在发生这样地情况了。因此我认为:在C++11新特性中,long long一定是最容易被接受的一个。多数程序员看到它时甚至不会意识到这是一个新特性。相应的,C++1_longlong c

关于在 Notion 中使用 Markdown 语法_notion怎么写markdown-程序员宅基地

文章浏览阅读1.4k次。习惯使用的 Markdown 的伙伴们应该知道,当需要加粗字体时,会首先输入。,也就是先键入**,后面紧接着输入需要加粗的文字,最后键入**。但是在 Notion 中,这个就不太行了。同样,行内公式、行内代码高亮、斜体等都是这个规则。,然后在里面填内容。_notion怎么写markdown

flask使用form表单报错:“KeyError: 'A secret key is required to use CSRF.'”_keyerror: 'form-程序员宅基地

文章浏览阅读4.5k次,点赞2次,收藏3次。flask使用form表单报错:“KeyError: ‘A secret key is required to use CSRF.’”报错详情:KeyError: 'A secret key is required to use CSRF.'Traceback (most recent call last)FFile &amp;quot;F:\Projects\flask_env\lib\site-pac..._keyerror: 'form

修改ubuntu ls 显示的目录底色_ubuntu中如何不显示绿色-程序员宅基地

文章浏览阅读884次。绿色底色很烦,看不清文件夹的名字在.bashrc里加一行,LS_COLORS=$LS_COLORS:'ow=1;32:'这样即可取消有些文件夹的绿色底色。其中ow的意思是OTHER_WRITABLE1的意思是粗体,32的意思是绿色前景参考:编码 颜色/动作 0 重新设置属性到缺省设置 1 设置粗体 2 设置一半亮度(模拟彩色显示器的颜色) 4 设置下划线(模拟彩色显示器的颜色) 5 设置闪烁 7 设置反_ubuntu中如何不显示绿色

django-celery-beat的使用-程序员宅基地

文章浏览阅读7.5k次,点赞3次,收藏7次。一、安装与配置使用pip安装包:$ pip install django-celery-beat将django_celery_beat模块添加到INSTALLED_APPSDjango项目中settings.py:#jdango时区配置# 官方用来修复CELERY_ENABLE_UTC=False and USE_TZ = False 时时间比较错误的问题;# 详情见:https://github.com/celery/django-celery-beat/pull/216/file_django-celery-beat

推荐文章

热门文章

相关标签