扩展欧几里德 POJ 1061
欧几里德的是来求最大公约数的,扩展欧几里德,基于欧几里德实现了一种扩展,是用来在已知a, b求解一组x,y使得ax+by = Gcd(a, b) =d(解一定存在,根据数论中的相关定理,证明是用裴蜀定理),关于欧几里德的证明请看上篇。
基本算法:基本算法:对于不完全为 0 的非负整数 a,b,gcd(a,b)表示 a,b 的最大公约数,必然存在整数对 x,y ,使得 gcd(a,b)=ax+by。
证明:设a>b;
1. 显然当b=0,gcd(a, b) = a;此时x=1, y=0;这个就是递归出口;
2. ab!=0 时
设 ax1+by1=gcd(a,b);
bx2+(a mod b)y2=gcd(b,a mod b);
根据朴素的欧几里德原理有 gcd(a,b)=gcd(b,a mod b)
则:ax1+by1=bx2+(a mod b)y2;
即:ax1+by1=bx2+(a-(a/b)*b)y2=ay2+bx2-(a/b)*by2;
根据恒等定理得:x1=y2; y1=x2-(a/b)*y2;(这个式子是递归的另外一部分,很重要的一步)
这样我们就得到了求解 x1,y1 的方法:x1,y1 的值基于 x2,y2.
上面的思想是以递归定义的,因为 gcd 不断的递归求解一定会有个时候 b=0,所以递归可以结束。
所以求代码可以如下
int exgcd(int a, int b, int &x, int &y)
{
if (b == )
{
x = ;
y = ;
return a; // a,b的最大公约数的求法(gcd)
}
int r = exgcd(b, a % b, x, y);
int t = x;
x = y;
y = t - a / b * y;
return r;//最大公约数
}
POJ 1061青蛙的约会这个题是求不定方程的解的,有题意可列方程(n-m)*s + k * L = x - y; 、
令a = n - m; b = L; c = x - y;
这个式子这时就是a * s + b * k = c;典型的不定方程
求解过程:
1. 首先计算gcd(a, b); 如果c不能整除gcd(a, b)那么就是没有解的,因为gcd(a, b)是a*s+b*k的线性组合的最小正整数, x,y∈z; 否则,方程两边同时除以gcd(a, b)得到新的方程a' * s + b' * k = c'; 这时候a', b'是互质的,所以gcd(a', b') = 1。
2. 利用上面所说的欧几里德算法求出方程a' * s + b' * k = 1的一组整数解x0,y0, 那么c' * x0, c' * y0就是方程a' * s + b' * k = c' 的一组整数解
3. 求方程组的通解,这时候就需要一些数论中的证明(a' * s + b' * k = c' 可以写成 a' * (s + t * b') + b' * (k - t * a') = c', t为整数, 所以通解s通=s + t * b', k通= k - t * a')
通解为:s通=s + t * b', k通= k - t * a'
所以它的最小正整数解为 (t % b' + b') % b';
代码如下:
#include <cstdio>
#include <iostream> typedef long long LL; int gcd(LL a, LL b)
{
return b == ? a : gcd(b, a % b);
}
void exgcd(LL a, LL b, LL &x, LL &y)
{
if (b == )
{
x = ;
y = ;
return;
}
exgcd(b, a % b, x, y);
LL t = x;
x = y;
y = t - (a / b) * y;
}
int main()
{ LL x, y, n, m, L;
while (~scanf("%I64d %I64d %I64d %I64d %I64d", &x, &y, &m, &n, &L))
{
LL a, b, c, r, k1, k2, GCD;
a = n - m;
b = L;
c = x - y;
GCD = gcd(a, b);
if (c % GCD != )
{
puts("Impossible");
}
else
{
a /= GCD;
b /= GCD;
c /= GCD;
exgcd(a, b, k1, k2);
k1 *= c;//为其中一个解
k1 = (k1 % b + b) % b;//最小正整数解
printf("%I64d\n", k1);
}
}
return ;
}
扩展欧几里德 POJ 1061的更多相关文章
- 数学#扩展欧几里德 POJ 1061&2115&2891
寒假做的题了,先贴那时写的代码. POJ 1061 #include<iostream> #include<cstdio> typedef long long LL; usin ...
- poj 1061 青蛙约会(扩展欧几里德)
题目链接: http://poj.org/problem?id=1061 题目大意: 中文题目,题意一目了然,就是数据范围大的出奇. 解题思路: 假设两只青蛙都跳了T次,可以列出来不定方程:p*l + ...
- ACM: POJ 1061 青蛙的约会 -数论专题-扩展欧几里德
POJ 1061 青蛙的约会 Time Limit:1000MS Memory Limit:10000KB 64bit IO Format:%lld & %llu Descr ...
- POJ 1061 青蛙的约会(扩展欧几里德)
点我看题目 题意 : 中文题不详述. 思路 : 设经过s步后两青蛙相遇,则必满足(x+m*s)-(y+n*s) = K*L(k = 0,1,2....) 变形得:(n-m)*s+K*L = x-y ; ...
- POJ 1061 青蛙的约会(扩展欧几里德算法)
题意:两只青蛙在同一个纬度上跳跃,给定每个青蛙的开始坐标和每秒跳几个单位,纬度长为L,求它们相遇的最短时间. 析:开始,一看只有一组数据,就想模拟一下,觉得应该不会超时,但是不幸的是TLE了,我知道这 ...
- poj 1061 青蛙的约会 (扩展欧几里得模板)
青蛙的约会 Time Limit:1000MS Memory Limit:10000KB 64bit IO Format:%I64d & %I64u Submit Status ...
- POJ 1061 青蛙的约会(扩展GCD求模线性方程)
题目地址:POJ 1061 扩展GCD好难懂.. 看了半天.最终把证明什么的都看明确了. .推荐一篇博客吧(戳这里),讲的真心不错.. 直接上代码: #include <iostream> ...
- POJ 2142 The Balance【扩展欧几里德】
题意:有两种类型的砝码,每种的砝码质量a和b给你,现在要求称出质量为c的物品,要求a的数量x和b的数量y最小,以及x+y的值最小. 用扩展欧几里德求ax+by=c,求出ax+by=1的一组通解,求出当 ...
- POJ 2891 扩展欧几里德
这个题乍一看跟剩余定理似的,但是它不满足两两互素的条件,所以不能用剩余定理,也是给了一组同余方程,找出一个X满足这些方程,如果找不到的话就输出-1 因为它不满足互素的条件,所以两个两个的合并,最后合成 ...
随机推荐
- Android学习----AndroidManifest.xml文件解析
一个Android应用程序的结构: 一.关于AndroidManifest.xml AndroidManifest.xml 是每个android程序中必须的文件.它位于整个项目的根目录,描述了pack ...
- Spring MVC PageNotFound.noHandlerFound No mapping found for HTTP request with URI
首先骂人,干他娘的,弄了两个小时原来的包倒错了!!唉TMD. 注意用IDEA倒包的时候一定要注意ModelAndView是 原因是import出错了!!应该是import org.springfram ...
- javascript写的ajax请求
<html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> &l ...
- Windows环境下 配置memcached (php)
memcached就不用介绍了-- 1:在Windows下安装memcached服务端软件,已经下载并上传云盘 ---传送门 记得带钥匙:ykrc 解压缩后里面的安装说明内有安装教程. 2:软件安装 ...
- __PUBLIC__模板文件路径配置
__PUBLIC__ 默认指向 项目文件下的Public文件夹 注意: __PUBLIC__不是一个常量,只在模板中进行替换,__ROOT__是一个常量 项目文件路径 defined('__PUBLI ...
- jquery animate函数实现
jquery animate 函数 实现动画效果 参数一 比如高度宽度 之类的:'-=50' 参数二 速度之类 <html xmlns="http://www.w3.org/1999/ ...
- python运维开发之第十天
一.多进程 1.进程模块 multiprocessing 简单的创建一个进程 #!/usr/bin/env python # -*- coding: utf- -*- # @Author : Will ...
- python学习第一课要点记录
写在要点之前的一段话,留给将来的自己:第一次参加编程的培训班,很兴奋很激动,之前都是自己在网上找免费的视频来看,然后跟着写一些课程中的代码,都是照着模子写,没有自己过多的思考.感觉这样学不好,除了多写 ...
- Android 开发中使用 SQLite 数据库
SQLite 介绍 SQLite 一个非常流行的嵌入式数据库,它支持 SQL 语言,并且只利用很少的内存就有很好的性能. 此外它还是开源的,任何人都可以使用它.许多开源项目((Mozilla, PHP ...
- oracle中的日期加减法
--加法 ) from dual; --加1年 ) from dual; --加1月 ,'yyyy-mm-dd HH24:MI:SS') from dual; --加1星期 ,'yyyy-mm-dd ...