欧几里德&扩展以及求解线性方程学习总结--附上poj1061解题报告
欧几里德算法:
欧几里德就是辗转相除法,调用这个gcd(a,b)这个函数求解a,b的最大公约数
公式:
gcd(a,b)=gcd(b,a%b);并且gcd(a,b)=gcd(b,a)=gcd(-a,b)=gcd(|a|,|b|)
代码:
int gcd(int a,int b)//递归
{
if(b==0)
return a;
return
gcd(b,a%b);
} int gcd(int a,int b)//递归简化
{
return b ? gcd(b,a%b) : a;
} int gcd(int a, int b)//迭代
{
while(b != 0)
{
int r = b;
b = a % b;
a = r;
}
return a;
}
扩展欧几里德:
2. b!=0的时候我们就按照欧几里得公式 gcd(a,b) = gcd(b,a%b)推导一般情况下x,y的值
gcd(a,b) = ax+by = gcd(b,a%b) = bx1+(a%b)y1;
那么a%b = a-a/b*b 注意这a/b 是语言除法,取整
那么就有bx1+(a%b)y1 = bx1+(a-a/b*b)y1 将其展开整理得 ax+by = ay1 + b(x1-a/b*y1)
那么得到一般情况下的 x = y1, y = x1-a/b*y1 既x 和 y 的解是通过递归得到的一组解,递归到最后就是 x = 1,y = 0 那么实际的 gcd(a,b) = ax+by 的解就可以在递归中得到
代码如下:
int exgcd(int a,int b,int &x,int &y)
{
if(b==0)
{
x=1;
y=0;
return a;
}
int r=exgcd(b,a%b,x,y);
int t=x;
x=y;
y=t-a/b*y;
return r;
} //递归方法 int exgcd(int m,int n,int &x,int &y)
{
int x1,y1,x0,y0;
x0=1; y0=0;
x1=0; y1=1;
x=0; y=1;
int r=m%n;
int q=(m-r)/n;
while(r)
{
x=x0-q*x1; y=y0-q*y1;
x0=x1; y0=y1;
x1=x; y1=y;
m=n; n=r; r=m%n;
q=(m-r)/n;
}
return n;
}//非递归方法
求解线性方程:
如果我们有线性方程: ax+by=c,(a,b,c一直)如果此方程有解,那么一定有 c%gcd(a,b) = 0,为什么呢?首先
a%gcd(a,b) = 0 = b%gcd(a,b); 那么c%gcd(a,b) = (ax+by)/gcd(a,b) = ax%gcd(a,b)+by%gcd(a,b) = 0+0=0
那么,接下来求解(x,y) ,首先我们通过exgcd(a,b) 就可以得到一组 x0,y0 ,那么我们现在通过这一组解得到通解:
我们取另一组未知解(x,y);那么就有 <1式>ax0+by0=ax+by=gcd(a,b);//(不管哪一组解,他们的gcd,也就是最大公约数都是一样的)
那么我们根据<1式>有 <2式>a(x-x0) = b(y0-y),现在我们定义 d = gcd(a,b);
由<2式>我们同除 d 得 <3式>a/d(x-x0) = b/d(y0-y);那么我们可以知道 a/d 和 b/d 现在互素,那么根据<3式>两个互素的数分别乘一个数要相等,那么就有x-x0 = t(b/d) y0-y = t(a/d);t为整数,也就是x-x0一定要是b/d的倍数,那么就可以得到 在有一组解 x0,y0 的情况下其他的解的通解如下式:
x=x0+t(b/d)
y=y0-t(a/d)
那么这样的解有无数多个,一般实际会要求一个条件下的最大或最小,
先给出求x最小的一个方法,下面引入poj1061青蛙的约会,就是要求所有的解当中的x最小
我们通过 exgcd(a,b) 求得了(x0,y0), 但是注意它不是满足ax+by=c 的一个解 ,因为我们只求得ax0+by0=gcd(a,b),但是这里c 和gcd(a,b) 还有一个倍数的关系,通过我们求得的ax0+by0=gcd(a,b) 两边同时 乘以 c/gcd(a,b) 才得到
ax0*(c/gcd(a,b)) + by0*(c/gcd(a,b)) = c;
那么根据上面的通解 x = x0+t(b/d);要使得x最小,那么就是取 t 最小 ,有一个技巧k=b/d,min = (x%k+k)%k;
poj1061
分析:那么假设跳了T次以后,青蛙A的坐标便是(x+m*T)%L,青蛙B的坐标为(y+n*T)%L,它们能够相遇的情况为(x+m*T)%L = (y+n*T)%L,那么他们之间跳的相对距离列式:(x+m*T) - (y+n*T)==P*L,其中P为某一个整数,变形一下得到(n-m)*T-P*L==x-y 我们设a=(n-m),b=L,c=x-y,T=x,P=y.于是便得到ax+by==c,直接利用欧几里得扩展定理可以得到一组x0,y0,接着用上面的方法即可:
上马:
// 132K 32MS
#include <stdio.h> #define ll __int64 ll x,y,a,b,c,d; ll exgcd(ll a,ll b)
{
if(!b) {x = 1; y = 0; return a;}
ll d = exgcd(b,a%b);
ll X = x;
x = y;
y = X - a/b*y;
return d;
} int main()
{
ll X,Y,n,m,L;
while(~scanf("%I64d%I64d%I64d%I64d%I64d",&X,&Y,&m,&n,&L))
{
a = n-m; b = L; c = X-Y;
d = exgcd(a,b);//先得到最大公约数,同时得到一组解x,y if(c%d != 0)//无解
{
printf("Impossible\n");continue;
} ll k = b/d;//最小解
x *= (c/d);//
x = (x%k+k)%k;
printf("%I64d\n",x);
}
return 0;
}
个人愚昧观点,欢迎指正和讨论
欧几里德&扩展以及求解线性方程学习总结--附上poj1061解题报告的更多相关文章
- [置顶] 白话二分匹配之最大匹配+附上hdu2063解题报告
最近开始学习图论的二分匹配,关于最大匹配做一次小总结,希望自己后面回头来看一目明了,也对刚接触的人有帮助: ps:开始有的文字很多....对于很多人来说一看到文字就烦啦...不过这个总结是针对匈牙利算 ...
- C#可扩展编程之MEF学习笔记(三):导出类的方法和属性
前面说完了导入和导出的几种方法,如果大家细心的话会注意到前面我们导出的都是类,那么方法和属性能不能导出呢???答案是肯定的,下面就来说下MEF是如何导出方法和属性的. 还是前面的代码,第二篇中已经提供 ...
- C#可扩展编程之MEF学习笔记(五):MEF高级进阶
好久没有写博客了,今天抽空继续写MEF系列的文章.有园友提出这种系列的文章要做个目录,看起来方便,所以就抽空做了一个,放到每篇文章的最后. 前面四篇讲了MEF的基础知识,学完了前四篇,MEF中比较常用 ...
- C#可扩展编程之MEF学习笔记(四):见证奇迹的时刻
前面三篇讲了MEF的基础和基本到导入导出方法,下面就是见证MEF真正魅力所在的时刻.如果没有看过前面的文章,请到我的博客首页查看. 前面我们都是在一个项目中写了一个类来测试的,但实际开发中,我们往往要 ...
- C#可扩展编程之MEF学习笔记(二):MEF的导出(Export)和导入(Import)
上一篇学习完了MEF的基础知识,编写了一个简单的DEMO,接下来接着上篇的内容继续学习,如果没有看过上一篇的内容, 请阅读:http://www.cnblogs.com/yunfeifei/p/392 ...
- C#可扩展编程之MEF学习笔记(一):MEF简介及简单的Demo
在文章开始之前,首先简单介绍一下什么是MEF,MEF,全称Managed Extensibility Framework(托管可扩展框架).单从名字我们不难发现:MEF是专门致力于解决扩展性问题的框架 ...
- C#可扩展编程之MEF学习
MEF系列文章: C#可扩展编程之MEF学习笔记(一):MEF简介及简单的Demo C#可扩展编程之MEF学习笔记(二):MEF的导出(Export)和导入(Import) C#可扩展编程之MEF学习 ...
- Matlab随笔之求解线性方程
原文:Matlab随笔之求解线性方程 理论知识补充: %矩阵除分为矩阵右除和矩阵左除. %矩阵右除的运算符号为“/”,设A,B为两个矩阵,则“A/B”是指方程X*B=A的解矩阵X. %矩阵A和B的列数 ...
- poj 2115 求线性同余方程 C Looooops(好理解欧几里德扩展定理怎么应用)
C Looooops Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 29061 Accepted: 8360 Descr ...
随机推荐
- WWDC 2015 - 概记
WWDC 2015已经过去快一个月了,今年似乎没有像去年那样变化巨大,一切都在慢慢演进,iOS.Mac OS.watchOS都变得越来越好. 新的三大平台的发布,iOS 9/Mac OS EL Cap ...
- activiti 引擎 数据库设计说明书
1.结构设计 1.1. 逻辑结构设计 Activiti使用到的表都是ACT_开头的. ACT_RE_*: ’RE’表示repository(存储),RepositoryService接口所操作的 ...
- Aviary 滤镜 教程 照片编辑器
Aviary是一个国外的非常强大的照片编辑器,各种功能,但是是以静态库的形式存在的,不开源,但是很好用. 1.到官网上面下载sdk https://github.com/AviaryInc/Mobil ...
- 《Unix网络编程》卷2 读书笔记 第2章- Posix IPC
1. 概述 Posix IPC 包括:Posix消息队列.Posix信号量.Posix共享内存区 Posix IPC在访问它们的函数和描述它们的信息上有一些类似点. 本章讲述所有这些共同属性:用于标识 ...
- unity, audio falloff
要达到声音随距离衰减的效果,需要使用3D音效,即把Spatial Blend设为1,然后再调节Min Distance和Max Distance(蓝色线框球体),并选择合适的Volume Rollof ...
- android 横竖屏限制如何配置
在开发android的应用中,有时候需要限制横竖屏切换.只需要在AndroidManifest.xml文件中加入android:screenOrientation属性限制. ndroid:screen ...
- Linux获取时间日期方法
linux中用shell获取昨天.明天或多天前的日期:在Linux中对man date -d 参数说的比较模糊,以下举例进一步说明:# -d, --date=STRING display time d ...
- 预热buffer pool
mysqldump -u root db_name table_name> /dev/null select * from ...
- linux清空日志文件内容 (转)
随着系统运行时间越来越长,日志文件的大小也会随之变得越来越大.如果长期让这些历史日志保存在系统中,将会占用大量的磁盘空间.用户可以直接把这些日志文件删除,但删除日志文件可能会造成一些意想不到的后果.为 ...
- 企业网站DDOS防护解决方案
随着网络的普及,越来越多的企业开始了上网之路,由于网络安全知识的欠缺,很多企业以为做一个网站就 等于 网络化了,于是狠花血本请专业网络公司制作出各种漂亮的网页.但做完才发现,网络上的各种漏洞的DDOS ...