The Elevator(扩展欧几里德好题)

全是电梯。

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;
 }

猜你喜欢

转载自blog.csdn.net/liuliu2333/article/details/81835286