题目描述
给出a,b,S三个数,你可以使用两种操作 a+=b和b+=a,问a或者b的位置上能否达到S。
第一步可有的状态(a,b)
第二步可 有的状态 (a,a+b) (a+b,a)
第一步可有的状态(a,b)
第二步可 有的状态 (a,a+b) (a+b,a)
第三步可有的状态 (a,a+b+a) (a+a+b,a+b) (a+b+a,a) (a+b,a+a+b)
例如 a=3 b=4 s=17
定义(a, b)
第一步:(3,4)//a = 3, b = 4
第二步:(3,7)// a = 3, b = a + b = 7
第三步:(3+7,7)// a = a + b = 10, b = 7
第四步:(10 + 7, 7)// a = a + b = 17, b = 7
此时 a到达s
输入
给出a,b,S三个数,
数据范围0<=a,b,s<=1e18
输出
a或者b的位置上能否达到S, 能输出YES, 否则输出NO
样例输入
1 2 3
3 4 5
3 4 17
样例输出
YES
NO
YES
题解:可以转换为是否可以求得x , y满足 ax + by = c, 且gcd(x, y) = 1.注意为0的情况。
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <queue>
#include <vector>
#include <deque>
#include <stack>
#include <string>
#include <string.h>
#include <bitset>
#include <map>
#include <set>
#include <assert.h>
typedef long long ll;
typedef long double ld;
#define pb push_back
#define SZ(X) ((int)X.size())
#define mp make_pair
#define Fi first
#define Se Second
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pli pair<ll,int>
#define pil pair<int,ll>
#define ALL(X) X.begin(),X.end()
#define RALL(X) X.rbegin(),X.rend()
#define rep(i,j,k) for(int i = j;i <= k;i ++)
#define per(i,j,k) for(int i = j;i >= k;i --)
#define mem(a,p) memset(a,p,sizeof(a))
using namespace std;
void Ex_gcd(ll a, ll b, ll &x, ll &y)
{
if(b == 0)
{
x = 1;
y = 0;
return;
}
ll x1, y1;
Ex_gcd(b, a%b, x1, y1);
x = y1;
y = x1-(a/b)*y1;
}
int main()
{
//
// freopen("f:\\test.in.txt","r",stdin);
// freopen("f:\\out1.txt","w",stdout);
ll a, b, c;
while(~scanf("%lld %lld %lld", &a, &b, &c)) {
ll d = __gcd(a,b);
ll x0, y0;
if(a == c || b == c || a + b == c) {
puts("YES");
} else if(c % d != 0 || a > c || b > c || (a + b) > c) {
puts("NO");
} else if(a == 0 || b == 0 || c == 0) {
if(a == 0 && b != 0) {
puts(c % b == 0 ? "YES" : "NO");
} else if(a != 0 && b == 0) {
puts(c % a == 0 ? "YES" : "NO");
} else if(a == 0 && b == 0 && c != 0) {
puts("NO");
}
} else {
Ex_gcd(a,b,x0,y0);
ll x = c / d * x0;
ll y = c / d * y0;
ll k1 = b / d; // x = x + k1 * t; //通解为x = x0 + (b / gcd) * t;
ll k2 = a / d; // y = y - k2 * t; // y = y0 - (a / gcd) * t;
x = (x % k1 + k1) % k1;
y = (c - a * x) / b;
assert(a * x + b * y == c);
bool fg = 0;
while(y > 0) {
if(__gcd(x, y) == 1) {
fg = 1;
break;
}
x += k1;
y -= k2;
}
puts(fg ? "YES" : "NO");
}
}
return 0;
}