You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
3.1 KiB
3.1 KiB
裴蜀定理(贝祖定理)
定理
对任何整数 a、b
和 m
,关于未知数 x
和 y
的线性丢番图方程(称为裴蜀等式):
\LARGE ax+by=m
- 有整数解时当且仅当
m
是a
及b
的最大公约数d=gcd(a,b)
的倍数。 - 裴蜀等式有解时必然有无穷多个整数解,每组解
x,y
都称为裴蜀数 - 可用扩展欧几里得算法求解裴蜀数
例子
例如,12
和42
的最大公约数是6
,则方程12x + 42y = 6
有解。
事实上有:
(−3)×12+1×42=6
4×12+(−1)×42=6
11×12+(-3)*42=6
- ...
用计算机帮着算一下:
#include <bits/stdc++.h>
using namespace std;
int main() {
for (int x = -100; x <= 100; x++)
for (int y = -100; y <= 100; y++)
if (2 * x + y * 7 == 1) cout << x << " " << y << endl;
return 0;
}
证明
看这个证明可能要好懂点 例:
\LARGE 2 * x + 4 * y = c
那么c
无论如何都是偶数,换句话来说,c
一定是2
的倍数2 = gcd(2,4)
\LARGE 3 * x + 9 * y = c
那么同理c
一定是3
的倍数,因为上述等于 : 3 * x + 3 * 3 * y = c
3 * (x + 3 * y) = c
,外面乘了个3
,那么c
再怎么都是3
的倍数,3 = gcd(3,9)
那么这个定理有什么用呢。当x,y
为整数解的时候,c
一定是gcd(a,b)
的倍数,那么我们就可以求得当为整数解的时候,c
的最小值肯定就是gcd(a,b)
//最大公约数的1
倍。
实现代码
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
scanf("%d", &n);
int d = 0, a;
for (int i = 1; i <= n; i++) {
scanf("%d", &a);
d = __gcd(d, abs(a));
}
printf("%d", d);
return 0;
}
#### 引理
给定a,b
,均是正整数且互质,那么由ax+by,x>=0,y>=0
不能凑出的最大数是ab-a-b
;
解法I:采用引理解题
#include<bits/stdc++.h>
using namespace std;
int main(){
int a, b;
scanf("%d %d",&a,&b);
printf("%d\n",a*b-a-b);
return 0;
}
解法II:采用爆搜解题
#include <bits/stdc++.h>
using namespace std;
int p, q, res;
/*
测试数据:
4 7
根据公式,最大无法凑出的是:4*7-4-7=17
*/
bool dfs(int x) {
if (x == 0) return true;
if (x >= p && dfs(x - p)) return true;
if (x >= q && dfs(x - q)) return true;
return false;
}
int main() {
scanf("%d %d", &p, &q);
for (int i = 1; i <= 1000; i++)
if (!dfs(i)) res = i;
printf("%d\n", res);
return 0;
}