标签:poj
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 95878 | Accepted: 17878 |
Description
Input
Output
Sample Input
1 2 3 4 5
Sample Output
4
题意就是解一个方程,即(x+m*t)-(y+n*t)=p*L。求满足方程的最小t。将方程变换为(n-m)*t+p*L=x-y。这个方程里面x,y,n,m都已知。
一开始不知道扩展欧几里得的方法,就一直遍历判断看能不能有符合条件的数值,提交了44次还是TLE。。。
(摘自百度百科)扩展欧几里德:
扩展欧几里德算法是用来在已知a, b求解一组x,y,使它们满足贝祖等式: ax+by = gcd(a,
b) =d(解一定存在,根据数论中的相关定理)。
欧几里德算法
<span style="font-size:12px;">#include<iostream> #include<cstdio> using namespace std; int x,y,q; void extend_Eulid(int a,int b){ if(b==0){ x=1;y=0;q=a; return; } extend_Eulid(b,a%b); int temp=x; x=y; y=temp-a/b*y; } int main(){ int a,b; cin>>a>>b; extend_Eulid(a,b); printf("%d=(%d)*%d+(%d)*%d\n",q,x,a,y,b); return 0; }</span>扩展算法
对于不完全为 0 的非负整数 a,b,gcd(a,b)表示 a,b 的最大公约数,必然存在整数对 x,y ,使得 gcd(a,b)=ax+by。
c++语言实现
<pre name="code" class="html">int exgcd(ll a,ll b,ll &x,ll &y) { if(a==0) { x=0;y=1; return b; } else { ll tx,ty; ll d=exgcd(b%a,a,tx,ty); x=ty-(b/a)*tx; y=tx; return d; } }
#include <iostream> #include <vector> #include <string> #include <cstring> #include <algorithm> using namespace std; long long d; void ex_gcd(long long a,long long b,long long &xx,long long &yy) { if(b==0) { xx=1; yy=0; d=a;//d为求出来的a,b的最小公约数 } else { ex_gcd(b,a%b,xx,yy); long long t=xx; xx=yy; yy=t-(a/b)*yy; } } int main() { long long x,y,m,n,L,xx,yy; cin>>x>>y>>m>>n>>L; ex_gcd(n-m,L,xx,yy); if((x-y)%d)//如果方程等式右边不能除以最小公约数,说明该方程没有解。 { cout<<"Impossible"<<endl; } else { xx=xx*((x-y)/d);//求出的xx,yy是方程等于最小公约数时的解,这时要将解扩大为(x-y)*d倍。 long long r=L/d; xx=(xx%r+r)%r;//此处求解的最小值 cout<<xx<<endl; } system("pause"); return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:poj
原文地址:http://blog.csdn.net/u010885899/article/details/46761621