POJ 1061 拓展欧几里德算法

本文探讨了两只青蛙在线上相约见面的问题,利用拓展欧几里德算法判断两者是否能在特定条件下相遇,并提供了解决方案的代码实现。

学习自http://www.cnblogs.com/ka200812/archive/2011/09/02/2164404.html,博主写得太好了,推荐!

青蛙的约会
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 77540 Accepted: 13085

Description

两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面。它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止。可是它们出发之前忘记了一件很重要的事情,既没有问清楚对方的特征,也没有约定见面的具体位置。不过青蛙们都是很乐观的,它们觉得只要一直朝着某个方向跳下去,总能碰到对方的。但是除非这两只青蛙在同一时间跳到同一点上,不然是永远都不可能碰面的。为了帮助这两只乐观的青蛙,你被要求写一个程序来判断这两只青蛙是否能够碰面,会在什么时候碰面。
我们把这两只青蛙分别叫做青蛙A和青蛙B,并且规定纬度线上东经0度处为原点,由东往西为正方向,单位长度1米,这样我们就得到了一条首尾相接的数轴。设青蛙A的出发点坐标是x,青蛙B的出发点坐标是y。青蛙A一次能跳m米,青蛙B一次能跳n米,两只青蛙跳一次所花费的时间相同。纬度线总长L米。现在要你求出它们跳了几次以后才会碰面。

Input

输入只包括一行5个整数x,y,m,n,L,其中x≠y < 2000000000,0 < m、n < 2000000000,0 < L < 2100000000。

Output

输出碰面所需要的跳跃次数,如果永远不可能碰面则输出一行"Impossible"

Sample Input

1 2 3 4 5

Sample Output

4

拓展欧几里德算法:对于任意a*x+b*y = gcd(a,b),以下算法可以求出满足该等式的一组解。
View Code
 1 int x,y;
 2 
 3 int GCD(int a,int b)
 4 {
 5     if(!b)
 6     {
 7         x = 1; y = 0; return a;
 8     }
 9     int temp,gcd;
10     gcd = GCD(b,a%b);
11     temp = x;
12     x = y;
13     y = x - (a/b)*y;
14     return gcd;
15 }

解析:为什么 b == 0的时候,x=1,y=0呢,因为b=0的话,原式就变成了a*x=gcd(a,0)=a。再考虑为什么y = temp - (a/b)*y,设第一层时等式为a*x+b*y=gcd(a,b),那么第二层就是
b*x1+(a%b)*y1 = gcd(b,a%b);由于gcd(a,b)==gcd(b,a%b),所以有a*x+b*y = b*x1+(a%b)*y1;考虑右边的式子,有b*x1+(a-a/b*b)*y1 = a*y1 + b*(x1-a/b)*y1(通过整数的除法得到);再与左边式子比较,很明显下一层的y1 = 上一层的x, y = x1 - (a/b)*y1.  (temp 存的就是 x1的值)。

这样便得到方程的一组解x,y。

对于一般等式a*x + b*y = c;则得到的解为x0 = x*c/gcd, y0 = y*c/gcd。(当c不能整除gcd时,无整数解)。若要得方程的所有整数解,一般的有x = x0 + b/gcd*k, y = y1 - a/gcd*k;k为任意整数。

View Code
 1 #include <iostream>
 2 #include <cstdio>
 3 
 4 using namespace std;
 5 
 6 __int64 x,y;
 7 
 8 __int64 GCD(__int64 a,__int64 b)
 9 {
10     if(!b)
11     {
12         x = 1;
13         y = 0;
14         return a;
15     }
16     __int64 temp,gcd;
17     gcd = GCD(b,a%b);
18     temp = x;
19     x = y;
20     y = temp - (a/b)*y;
21     return gcd;
22 }
23 
24 int main()
25 {
26     __int64 A,B,m,n,L;
27     while(~scanf("%I64d%I64d%I64d%I64d%I64d",&A,&B,&m,&n,&L))
28     {
29         __int64 a = n - m;
30         __int64 b = L;
31         __int64 c = A - B;
32         __int64 gcd = GCD(a,b);
33         if(c%gcd)
34         {
35             printf("Impossible\n");
36             continue;
37         }
38         x = x*(c/gcd);
39         y = y*(c/gcd);
40         __int64 ans = x*gcd/b;
41         ans = x - ans*b/gcd;
42         if(ans < 0)
43             ans += b/gcd;
44         printf("%I64d\n",ans);
45     }
46     return 0;
47 }

 

根据原作 https://pan.quark.cn/s/459657bcfd45 的源码改编 Classic-ML-Methods-Algo 引言 建立这个项目,是为了梳理和总结传统机器学习(Machine Learning)方法(methods)或者算法(algo),和各位同仁相互学习交流. 现在的深度学习本质上来自于传统的神经网络模型,很大程度上是传统机器学习的延续,同时也在不少时候需要结合传统方法来实现. 任何机器学习方法基本的流程结构都是通用的;使用的评价方法也基本通用;使用的一些数学知识也是通用的. 本文在梳理传统机器学习方法算法的同时也会顺便补充这些流程,数学上的知识以供参考. 机器学习 机器学习是人工智能(Artificial Intelligence)的一个分支,也是实现人工智能最重要的手段.区别于传统的基于规则(rule-based)的算法,机器学习可以从数据中获取知识,从而实现规定的任务[Ian Goodfellow and Yoshua Bengio and Aaron Courville的Deep Learning].这些知识可以分为四种: 总结(summarization) 预测(prediction) 估计(estimation) 假想验证(hypothesis testing) 机器学习主要关心的是预测[Varian在Big Data : New Tricks for Econometrics],预测的可以是连续性的输出变量,分类,聚类或者物品之间的有趣关联. 机器学习分类 根据数据配置(setting,是否有标签,可以是连续的也可以是离散的)和任务目标,我们可以将机器学习方法分为四种: 无监督(unsupervised) 训练数据没有给定...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值