求解模线性方程
Posted BobHuang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了求解模线性方程相关的知识,希望对你有一定的参考价值。
我曾经在数论里谈过扩展欧几里得算法只有实现,我知道它可以求模线性方程的解,但是具体也没有想过,因为同余是数论中问题
现在来填下坑
什么是同余
给定一个正整数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; }
The Balance
You are asked to help her by calculating how many weights are required.
Input
The end of the input is indicated by a line containing three zeros separated by a space. It is not a dataset.
Output
- You can measure dmg using x many amg weights and y many bmg weights.
- The total number of weights (x + y) is the smallest among those pairs of nonnegative integers satisfying the previous condition.
- The total mass of weights (ax + by) is the smallest among those pairs of nonnegative integers satisfying the previous two conditions.
No extra characters (e.g. extra spaces) should appear in the output.
Sample Input
700 300 200 500 200 300 500 200 500 275 110 330 275 110 385 648 375 4002 3 1 10000 0 0 0
Sample Output
1 3 1 1 1 0 0 3 1 1 49 74 3333 1
让你求ax+by=c中|x|+|y|的最小值。
exgcd找到通解,再找那两个相近的值
#include<stdio.h> #define abs(a) ((a)<0?-(a):(a)) 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 a,b,d; while(~scanf("%d%d%d",&a,&b,&d)) { if(!a&&!b&&!d)break; int x,y; la(a,b,x,y); int x1=(x*d%b+b)%b; int y1=abs(d-a*x1)/b; y=(y*d%a+a)%a; x=abs(d-b*y)/a; if(x+y>x1+y1) x=x1,y=y1; printf("%d %d\\n",x,y); } return 0; }
以上是关于求解模线性方程的主要内容,如果未能解决你的问题,请参考以下文章