POJ - 1061 青蛙的约会(扩展欧几里得)
生活随笔
收集整理的這篇文章主要介紹了
POJ - 1061 青蛙的约会(扩展欧几里得)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接:點擊查看
題目大意:兩只青蛙在一個單向循環數軸上跳動,給出初始位置和每秒跳動的距離以及數軸長度,問是否可以相遇,若能相遇求出最小時間
題目分析:自從第一次接觸擴展歐幾里得以來已經有半年時間了,期間遇到這個題目三次,每一次都是照著網上的題解茍且A掉的,前兩天去了一次數論的集訓,瞬間就豁然開朗,終于明白了擴展歐幾里得的正確用法,并且第一次自己完完整整的解決掉了這個模板題。。我太菜了。。直接進入正題:
首先根據題意,我們可以假設兩只青蛙是可以相遇的,那么就可以表示成下面的公式:(設t為第t秒相遇)
(x+t*m)%L=(y+t*n)%L
根據同余公式可以相加減,我們進行移項,得到兩種情況:
(x-y)%L=t*(n-m)%L和(y-x)%L=t*(m-n)%L
根據同余公式,我們可以寫成下面的兩種等式:
t*(n-m)+k*L=(x-y)和t*(m-n)+k*L=(y-x)
到了這里我們就可以與擴展歐幾里得的公式一一對應上了:
A*x+B*y=C
接下來我們只需要套入模板求出t即可,這里有一點需要注意的,就是擴展歐幾里得只能處理正數,但n-m不一定是正數,所以我們分類討論一下即可:
最后套公式就好了,上代碼:
#include<iostream> #include<cstdlib> #include<string> #include<cstring> #include<cstdio> #include<algorithm> #include<climits> #include<cmath> #include<cctype> #include<stack> #include<queue> #include<list> #include<vector> #include<set> #include<map> #include<sstream> using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=1e5+100;LL ex_gcd(LL a,LL b,LL &x,LL &y) {if(b==0){x=1;y=0;return a;}LL ans=ex_gcd(b,a%b,y,x);y-=a/b*x;return ans; }int main() { // freopen("input.txt","r",stdin);LL x,y,m,n,L;while(scanf("%lld%lld%lld%lld%lld",&x,&y,&m,&n,&L)!=EOF){LL X,Y;int A,B,C;if(m-n>0){A=m-n;B=L;C=y-x;}else{A=n-m;B=L;C=x-y;}LL d=ex_gcd(A,B,X,Y);if(C%d!=0){printf("Impossible\n");continue;}B/=d;X=X*C/d;X=(X%B+B)%B;printf("%lld\n",X);}return 0; }?
總結
以上是生活随笔為你收集整理的POJ - 1061 青蛙的约会(扩展欧几里得)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HDU - 5667 Sequence(
- 下一篇: HDU - 3694 Fermat Po