One Person Game
Time Limit: 2 Seconds Memory Limit: 65536 KB
There is an interesting and simple one person game. Suppose there is a number axis under your feet. You are at point A at first and your aim is point B. There are 6 kinds of operations you can perform in one step. That is to go left or right by a,b and c, here c always equals to a+b.
You must arrive B as soon as possible. Please calculate the minimum number of steps.
Input
There are multiple test cases. The first line of input is an integer T(0 < T ≤ 1000) indicates the number of test cases. Then T test cases follow. Each test case is represented by a line containing four integers 4 integers A, B, a and b, separated by spaces. (-231 ≤ A, B < 231, 0 < a, b < 231)
Output
For each test case, output the minimum number of steps. If it's impossible to reach point B, output "-1" instead.
Sample Input
2
0 1 1 2
0 1 2 4
Sample Output
1
-1
题意:给你一个起点和终点,每次可以向左或向右走a步或b或c步,c=a+b;问最小步数;
根据公式ax+by=c;,当x,y同号时等于max(x,y),当a,b异号时等于(abs(x)+abs(y)),因为a,b大于0,所以不管x,y同号还是异号都是当x,y,最接近时,答案最小,写出通式
x=x1+b/(gcd)*k,y=y1-a/gcd*k; 假设x,y相等,k=(y-x)/(a+b),因为x,y不一定相等,所以枚举k附近的点
大意:一维坐标轴,有A和B两个地方,现在从A到B,每次可以向任意方向走a、b或者c的距离,其中c=a+b,问能不能走到B,能的话最少走几次。
首先可以推出这个式子:a*x+b*y+c*z=|B-A|然后又因为c=a+b,所以其实可以化成a*x+b*y=|B-A|。所以需要用扩展gcd求出x,y,但是这个x,y有可能不是最优的,为什么呢?为了让步数最小就要拉近x,y的距离,使|x-y|最小。怎么拉近,
下面来看通解方程:
x = x0 + (b/gcd)*t
y = y0 – (a/gcd)*t
实际上是关于x,y关于t的两条直线(他们必有交叉点)。
可以设x==y,然后解出那个对应的t
,得到此时的一组解(t=(y0-x0)/((a+b)/gcd))但是实际上有可能无法使x==y(没有整数t),所以算出来的t接近于交叉点的t(有可能是小数),所以可能也不是最优解,所以需要增加一次t+1,t-1,这样比较3个t得到的结果(x,y同为正或同为负时,绝对值大的那个值(c的存在,a和b合并为c),一正一负就是绝对值和),其中小的一个必是最优解。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm> #define INF 0x7fffffff
#define EPS 1e-12
#define MOD 100000007
#define PI 3.14159265357979823846
#define N 100005 using namespace std; typedef long long ll; ll e_gcd(ll a, ll b, ll &x, ll &y)
{
ll d = a;
if (b != )
{
d = e_gcd(b, a%b,y, x);
y = y - a / b * x;
}
else
{
x = ; y = ;
}
return d;
} ll cal(ll a, ll b, ll l)
{
ll x, y;
ll gcd = e_gcd(a, b, x, y);
if (l%gcd != ) return -;
x *= l / gcd;
y *= l / gcd;
a = a / gcd;
b = b / gcd;
ll ans = ((ll)INF)*((ll)INF), f;
//下面来看通解方程:
// x = x0 + (b / gcd)*t
// y = y0 –(a / gcd)*t
// 实际上是关于x, y关于t的两条直线(他们必有交叉点)。
// 可以设x == y,然后解出那个对应的t
// , 得到此时的一组解(t = (y0 - x0) / ((a + b) / gcd))
//但是实际上有可能无法使x == y(没有整数t)
ll mid = (y - x) / (a + b);
for (ll T = mid - ; T <= mid + ; T++)
{
// 当x, y同号时等于max(x, y),先走几步(a+b)的,再走几步单独的
if (abs(x + b * T) + abs(y - a * T) == abs(x + b * T + y - a * T))
f = max(abs(x + b * T), abs(y - a * T));
else//当a,b异号时等于(abs(x)+abs(y))
f = fabs(x - y + (a + b)*T);
ans = min(ans, f);
}
return ans;
} int main()
{
ll A, B, a, b, x, y;
int t;
cin >> t;
while (t--)
{
cin >> A >> B >> a >> b;
ll l = B - A;
ll ans = cal(a, b, l);
if (ans == -) cout << "-1"<<endl;
else cout << ans << endl;
}
return ;
}
ZOJ 3593 One Person Game(拓展欧几里得求最小步数)的更多相关文章
-
ZOJ 3609 Modular Inverse(拓展欧几里得求最小逆元)
Modular Inverse Time Limit: 2 Seconds Memory Limit: 65536 KB The modular modular multiplicative ...
-
gcd模板(欧几里得与扩展欧几里得、拓展欧几里得求逆元)
gcd(欧几里得算法辗转相除法): gcd ( a , b )= d : 即 d = gcd ( a , b ) = gcd ( b , a mod b ):以此式进行递归即可. 之前一直愚蠢地以为辗 ...
-
ZOJ 3593.One Person Game-扩展欧几里得(exgcd)
智障了,智障了,水一水博客. 本来是个水题,但是for循环遍历那里写挫了... One Person Game Time Limit: 2 Seconds Memory Limit: 655 ...
-
Modular Inverse (拓展欧几里得求逆元)
The modular modular multiplicative inverse of an integer a modulo m is an integer xsuch that a-1≡x ( ...
-
ZOJ - 3593 One Person Game (扩展欧几里得)
题意:一个人在坐标A,要前往坐标B的位置.可以往左或往右走a,b,a+b个单位,求到达B的最小步数. 分析:扩展欧几里得算法求解线性方程的套路不变.令C=fabs(A-B),c = a+b, 扩展gc ...
-
POJ 1061 青蛙的约会(拓展欧几里得求同余方程,解ax+by=c)
青蛙的约会 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 122871 Accepted: 26147 Descript ...
-
拓展欧几里得求 ax + by = c的通解(a >;=0, b >;= 0)
#include <iostream> #include <cstdio> #include <algorithm> #include <vector> ...
-
POJ 2891 Strange Way to Express Integers(拓展欧几里得)
Description Elina is reading a book written by Rujia Liu, which introduces a strange way to express ...
-
Looooops(求解同余方程、同余方程用法)【拓展欧几里得】
Looooops(点击) A Compiler Mystery: We are given a C-language style for loop of type for (variable = A; ...
随机推荐
-
GIS项目中数据开源、工具开源、开发开源的解决方案
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 摆脱免费地图开发包的约束,拒绝商业地图软件的费用,高效.精确.完备是我 ...
-
知方可补不足~SqlServer连接的复用MultipleActiveResultSets
回到目录 MultipleActiveResultSets可以使数据库连接复用,但当你上了moebius这种集群工具后,这个选项不能开启(默认是false),当你使用EF等ORM工具时,这个选项会默认 ...
-
ACM: 限时训练题解-Runtime Error-二分查找
Runtime Error Bahosain was trying to solve this simple problem, but he got a Runtime Error on one ...
-
字符串转Json对象
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Web.S ...
-
Hql整理
一.实体类直接查询 hql语句:(没有select * 表示默认选择全部属性) public static String GET_ALLUSERINFO="from UserEntity&q ...
-
Peer-to-Peer (P2P) communication across middleboxes
Internet Draft B. FordDocument: draft-ford-midcom- ...
-
(转)mobile cpu上禁用alpha test的相关总结
转自:http://www.cnblogs.com/TracePlus/p/4037165.html 因为,每家芯片的特性不同,根据向framebuffer写法的不同,分为tile-based的mob ...
-
POJ2429_GCD &;amp; LCM Inverse【Miller Rabin素数測试】【Pollar Rho整数分解】
GCD & LCM Inverse Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 9756Accepted: 1819 ...
-
[Boolan-C++学习笔记]第一周整理
1.两种典型类 Complex 无指针 String 有指针 编写思路差异较大 2.使用Class声明:Object Based.类与类之间的关系:Object Oriented 3.头文件的布局 # ...
-
easyui-layout系列之布局(1)
1.Layout布局 通过 $.fn.layout.defaults 重写默认的 defaults. 布局(layout)是有五个区域(北区 north.南区 south.东区 east.西区 wes ...