码迷,mamicode.com
首页 > 其他好文 > 详细

[数论]ZOJ3593 One Person Game

时间:2015-04-01 00:03:01      阅读:214      评论:0      收藏:0      [点我收藏+]

标签:

题意:一个人要从A走到B  只能走a布、b步、(a+b)步,可以往左或右走

     问 最少要走几步,不能走到的输出-1

 

可以列出方程 ax+by=A-B

或者     ax+(a+b)y=A-B

或者     bx+(a+b)y=A-B

要取这三个方程的最小的(x+y)

 

根据ax+by=gcd(a, b) 

当A-B不是gcd的倍数时 就不能走到

 

利用ex_gcd可以分别求出这三个方程的解,但求出的这组并非最小的

因此利用枚举斜率 得到的交点为最小的一组解

 

技术分享
 1 LL exgcd(LL a,LL b,LL &x,LL &y)
 2 {
 3     LL d=a;
 4     if(b!=0)
 5     {
 6         d=exgcd(b,a%b,y,x);
 7         y-=(a/b)*x;
 8     }
 9     else  x=1,y=0;
10     return d;
11 }
12 LL Abs(LL x)
13 {
14     return x<0? -x:x;
15 }
16 LL A;
17 LL gao(LL a, LL b)
18 {
19     LL x, y;
20     LL g=exgcd(a, b, x, y);
21     x=x*(A/g), y=y*(A/g);
22     a/=g, b/=g;
23 
24     LL ans=Abs(x)+Abs(y);
25     for(int i=-10;i<10;i++)
26         ans=min(ans, Abs(x+(-x/b+i)*b)+Abs(y-(-x/b+i)*a));
27     for(int i=-10;i<10;i++)
28         ans=min(ans, Abs(x+(y/a+i)*b)+Abs(y-(y/a+i)*a));
29     return ans;
30 }
31 int main()
32 {
33     int t;
34     LL B,a,b;
35     cin>>t;
36     while(t--)
37     {
38         cin>>A>>B>>a>>b;
39         A=Abs(A-B);
40         if(!A)
41         {
42             puts("0");
43             continue;
44         }
45         if(A%__gcd(a, b))
46         {
47             puts("-1");
48             continue;
49         }
50         cout<<min(gao(a, b), min(gao(a+b, a), gao(a+b, b)))<<endl;
51     }
52     return 0;
53 }
ZOJ 3593

 

[数论]ZOJ3593 One Person Game

标签:

原文地址:http://www.cnblogs.com/Empress/p/4382122.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!