全是电梯。
Philo正处于高度为0的一个平台上,在他面前的一个平面,全是上上下下的电梯。
Philo想要离开这里,请你帮帮他。
电梯世界规则:这里的电梯所能到达的层数皆为整数层,当Philo进入电梯,他只能选择上升a层或者下降b层(电梯只有这两种选择且a,b不同时为0)。对于任意整数层都有无限的电梯可乘坐(前提是Philo能够到达这一层)。
Philo在第0层,现在请你帮助Philo到达第nn层。如果可以请输出"YES",并输出他的合法的最小解。否则输出"NO"。
Input
每组测试数据输入三个整数n,a,b;
含义如题上所述
输入到文件结束;
-1e9<= n <=1e9
0<= a, b <=1e9
Output
若能够通过一定的次数使Philo到达第nn层,则先输出YES,下一行输出合法的最小解,否则输出NO.
Sample Input 1
3 6 9 4 9 3
Sample Output 1
YES 2 1 NO
题意:给定一个n,a,b问从0开始+a-b,正整数次(包括0)到n,问最小的a,和b的次数。
注意好特判。公式x=x0+(b/gcd)*t;y=y0+(a/gcd)*t;
#include<bits/stdc++.h>
using namespace std;
long long exgcd(long long a,long long b,long long &x,long long &y)
{
if(b==0)
{
x=1;y=0;return a;
}
long long r=exgcd(b,a%b,x,y);
long long tmp=x;x=y;y=tmp-a/b*y;
return r;
}
int main()
{
long long n,a,b;
while(~scanf("%lld %lld %lld",&n,&a,&b))
{
if(n==0)
{
printf("YES\n0 0\n");continue;
}
long long x,y;
long long k=exgcd(a,-b,x,y);
if(a==0)
{
if(b==0)
{
printf("NO\n");
continue;
}
if(n>0)
printf("NO\n");
else if(n%b==0)
printf("YES\n%lld %lld\n",0,abs(n/b));
else
printf("NO\n");
continue;
}
if(b==0)
{
if(n<0)
printf("NO\n");
else if(n%a==0)
printf("YES\n%lld %lld\n",abs(n/a),0);
else
printf("NO\n");
continue;
}
if(n>0&&n%a==0)
{
printf("YES\n%lld %lld\n",n/a,0);continue;
}
if(n<0&&n%b==0)
{
printf("YES\n%lld %lld",0,n/b);
}
if(n%k)
{
printf("NO\n");
}
else
{
long long w=abs(a/k*b);
a=abs(a/k);b=abs(b/k);
k=n/k;x*=k;y*=k;
long long xx=(x%b+b)%b;//将x变为0~(b/gcd)
int o=(xx-x)/b;
x=xx;
y=y+a*o;
if(y>=0)
{
printf("YES\n%lld %lld\n",x,y);continue;
}
long long yy=(y%a+a)%a;
o=(yy-y)/a;
y=yy;
x+=b*o;
printf("YES\n%lld %lld\n",x,y);
}
}
return 0;
}