HackerRank leonardo-and-lucky-numbers —— 模线性方程的通解
题目链接:https://vjudge.net/problem/HackerRank-leonardo-and-lucky-numbers
题解:
1.根据扩展欧几里得:7*x + 4*y = gcd(7,4) = 1,必有整数解,其中一组为(-1,2),通解为:(-1+4*k, 2-7*k)。
2.当:7*x + 4*y = n,其中一组解为(-n,2*n),通解为:(-n+4*k, 2*n-7*k)。
3.若要上式有解,则通解(-n+4*k, 2*n-7*k)中必须至少有一对非负的整数解。
4. x = -n+4*k >=0 && y = 2*n-7*k >=0 ,推出k的范围: n/4<=k<=2n/7。然后再在这个范围内枚举k,得到x,y,x、y为非负数,并且7x+4y = n。
代码如下:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <vector> 6 #include <cmath> 7 #include <queue> 8 #include <stack> 9 #include <map> 10 #include <string> 11 #include <set> 12 #define ms(a,b) memset((a),(b),sizeof((a))) 13 //#define LOCAL 14 using namespace std; 15 typedef long long LL; 16 const int INF = 2e9; 17 const LL LNF = 9e18; 18 const int mod = 1e9+7; 19 const int maxn = 200000+10; 20 21 int main() 22 { 23 LL q, n; 24 scanf("%lld",&q); 25 while(q--) 26 { 27 LL x, y, k, n; 28 int B = 0; 29 scanf("%lld",&n); 30 for(k = n/4-1; k<=(2*n)/7+1; k++) //除法可能除不尽,所以要左右各扩一个单位 31 { 32 x = -1LL*n+1LL*4*k; 33 y = 1LL*2*n-1LL*7*k; 34 if(x<0 ||y<0) continue; 35 if(7*x+4*y==n) 36 { 37 B = 1; 38 break; 39 } 40 } 41 if(B) puts("Yes"); 42 else puts("No"); 43 } 44 }