求解模線性方程
我曾經在數論裏談過擴展歐幾裏得算法只有實現,我知道它可以求模線性方程的解,但是具體也沒有想過,因為同余是數論中問題
現在來填下坑
什麽是同余
給定一個正整數m,如果兩個整數a和b滿足(a-b)能夠被m整除,即(a-b)/m得到一個整數,那麽就稱整數a與b對模m同余,記作a≡b(mod m)。
算法導論中文版P868 31.4求解模線性方程
給了ax≡b(mod n)
假設已知a,b和n,希望求出所有滿足ax≡b(mod n)的對模n的x的值
同余方程 ax≡b (modn)對於未知數 x 有解,當且僅當 gcd(a,n) | b。且方程有解時,方程有 gcd(a,n) 個解。
求解方程 ax≡b (modn) 相當於求解方程 ax+ny= b, (x, y為整數)。
生理周期OpenJ_Bailian - 4148
人生來就有三個生理周期,分別為體力周期、感情周期和智力周期,它們的周期長度分別為23天、28天和33天。每一個周期中有一天是高峰。在高峰這天,人會在相應的方面表現出色。例如,在智力周期的高峰,人會思維敏捷,註意力容易高度集中。因為三個周期的長度不同,所以通常三個周期的高峰不會落在同一天。對於每個人,想知道何時三個高峰落在同一天。對於每個周期,會給出從當前年份的第一天開始,到出現高峰的天數(不一定是第一次高峰出現的時間)。給定一個從當年第一天開始的天數,你的任務是輸出從給定時間開始(不包括給定時間),下一次三個高峰落在同一天的時間(距給定時間的天數)。例如:給定時間為10,下次出現三個高峰同一天的時間是12,則輸出2(註意這裏不是3)。
Input輸入包含多組數據,每一組數據由四個整數組成,數據以-1 -1 -1 -1 結束。
對於四個整數p, e, i和d,p, e, i分別表示體力、情感和智力高峰出現的時間(時間從當年的第一天開始計算)。d是給定的時間,可能小於p, e或i。所有給定時間是非負的並且小於或等於365,所求的時間小於或等於21252。Output從給定時間起,下一次三個高峰同一天的時間(距離給定時間的天數)。Sample Input
0 0 0 0 0 0 0 100 5 20 34 325 4 5 6 7 283 102 23 320 203 301 203 40 -1 -1 -1 -1
Sample Output
Case 1: the next triple peak occurs in 21252 days. Case 2: the next triple peak occurs in 21152 days. Case 3: the next triple peak occurs in 19575 days. Case 4: the next triple peak occurs in 16994 days. Case 5: the next triple peak occurs in 8910 days. Case 6: the next triple peak occurs in 10789 days.
問多少天後三個高峰期同天,如果利用循環也沒毛病,這個用模性方程要怎麽解麽
以前的兩個值變為三個,那就是要求滿足兩個之後,還滿足第三個的
x+d≡p(mod 23)
x+d≡e(mod 28)
x+d≡i(mod 33)
往下解一下就好了
#include<stdio.h> void la(int a,int b,int &x,int &y) { if(!b) { x=1; y=0; return; } la(b,a%b,x,y); int t=x; x=y; y=t-a/b*y; } int main() { int p,e,i,d,ca=1; while(~scanf("%d%d%d%d",&p,&e,&i,&d)) { if(p==-1&&e==-1&&i==-1&d==-1)break; int ans=0,x,y; la(28*33,23,x,y); ans+=28*33*x*p; la(23*33,28,x,y); ans+=23*33*x*e; la(28*23,33,x,y); ans+=28*23*x*i; x=(ans-d)%21252; if (x<=0)x+=21252; printf("Case %d: the next triple peak occurs in %d days.\n",ca++,x); } return 0; }
精簡版
#include<stdio.h> int main() { int p,e,i,d,ca=1; while(~scanf("%d%d%d%d",&p,&e,&i,&d)){ if(p==-1&&e==-1&&i==-1&d==-1)break; int x=(5544*p+14421*e+1288*i-d+21252)%21252; if(x==0)x=21252; printf("Case %d: the next triple peak occurs in %d days.\n",ca++,x); } return 0; }
求解模線性方程