我正在编写一个程序,对于任何给定的正整数a< b<如果存在ax + by = c的解,则c将输出YES,其中x和y也是正整数(x,y> 0),或者如果没有解,则输出NO。请记住,我需要处理大数字。
我解决这个问题的方法是从c中减去b,然后检查这个数字是否可以被a除。
这是我的代码:
#include <stdio.h>
#include <stdlib.h>
int main(){
unsigned long long int a, b, c;
scanf("%I64u %I64u %I64u", &a, &b, &c);
while(c>=a+b){ //if c becomes less than a+b, than there's no sollution
c-=b;
if(c%a==0){
printf("YES");
return 0;
}
}
printf("NO");
return 0;
}
是否有一种更优化的方法来找到更好的ax + by = c有积极的解决方案?我尝试阅读关于线性丢番图方程,但我找到的只是找到整数解(但不是正数)的方法。
答案 0 :(得分:2)
到目前为止我的方法。
对于比较,很难找到花费超过一秒钟的例子,但在决定数千个随机方程时,性能差异是显而易见的。 This Lecture有一个解决方案可以找到积极的数量 线性丢番图方程的解。
typedef unsigned long long int BigInt;
int pos_solvable(BigInt a, BigInt b, BigInt c) {
/* returns 1 if there exists x, y > 0 s.t. ax + by = c
* where 0 < a < b < c
* returns 0, otherwise
*/
BigInt gcd = a, bb = b, temp;
while (bb) { /* Euclidean Algorithm */
temp = bb;
bb = gcd % bb;
gcd = temp;
}
if (c % gcd) { /* no integer (or positive) solution */
return 0;
} else {
/* Extended Euclidean Algorithm */
BigInt s = 0, old_s = 1;
BigInt t = 1, old_t = 0;
BigInt r = b / gcd, old_r = a / gcd;
while (r > 0) {
BigInt quotient = old_r / r;
BigInt ds = quotient * s;
BigInt dt = quotient * t;
if (ds > old_s || dt > old_t)
return 0; /* will give non-positive solution */
temp = s;
s = old_s - ds;
old_s = temp;
temp = t;
t = old_t - dt;
old_t = temp;
temp = r;
r = old_r - quotient * r;
old_r = temp;
}
return 1;
}
}
答案 1 :(得分:1)
以下是评论,但对评论部分来说太大了。
这是为了帮助其他人更深入地探讨这个问题。
OP:如果你愿意,可以在你的帖子中加入任何内容。
仍然需要一些具有挑战性的a,b,c
。
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//#define LLF "%I64u"
#define LLF "%llu"
int main(void) {
unsigned long long int a, b, c, x, y, sum, c0;
// scanf(LLF LLF LLF, &a, &b, &c);
c = c0 = ULLONG_MAX;
b = 10000223;
a = 10000169;
y = 0;
sum = a + b;
time_t t0 = time(NULL);
while (c >= sum) { //if c becomes less than a+b, than there's no solution
c -= b;
if (c % a == 0) {
break;
}
}
if (c % a == 0) {
y = (c0 - c) / b;
x = c / a;
printf("YES " LLF "*" LLF " + " LLF "*" LLF " = " LLF "\n", a, x, b, y, c);
} else {
printf("NO\n");
}
time_t t1 = time(NULL);
printf("time :" LLF "\n", (unsigned long long) (t1 - t0));
return 0;
}
输出
YES 10000169*1844638544065 + 10000223*4688810 = 18446697184563946985
time :0