ZOJ 3593 One Person Game(拓展欧几里得求最小步数)
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; ...
随机推荐
- 记录一个bootstrap因js加载顺序导致的问题(tstrap-table-mobile.min.js:7 Uncaught TypeError: Cannot read property 'defaults' of undefined)
问题描述: 网上找了会没看到答案,然后看了下源码,发现也没有问题,想到js加载的顺序,改了下,发现问题没了. 正确的顺序: 我之前把 <script src="/js/plugins/ ...
- python3 快速排序
思路 第一步:找到一个随机的数,一般都是第一个数,也就是left,递归中也用left,放到缓存中,专业叫 基准值,基准值是要放在中间的. 第二步:最左边空出一个位置就是索引left的位置,所以从右向左 ...
- core文件介绍
原文链接:http://team.eyou.com/?p=27 如有侵犯您的版权,请联系windeal12@qq.com linux下,产生core文件,和不产生core文件的条件: 当我们的程序崩溃 ...
- 20165202 实验二 Java面向对象程序设计
实验二 Java面向对象程序设计 一.实验报告封面 课程:Java程序设计 班级:1652班 姓名:贾海粟 学号:20165202 指导教师:娄嘉鹏 实验日期:2018年4月16日 实验时间:15:3 ...
- Django部署时为什么要用 uWSGI与 Nginx? 以及 WSGI,uwsgi等协议
Django框架的服务器架构一般是 Nginx + uWSGI + Django (1)一些基本概念 1 WSGI协议,uwsgi协议 WSGI协议(通讯协议):Python用于Web开发的协议(用于 ...
- live555源码分析
live555源代码下载(VC6工程):http://download.csdn.net/detail/leixiaohua1020/6374387 liveMedia 项目(http://www.l ...
- 《Unity 3D游戏客户端基础框架》消息系统
功能分析: 首先,我们必须先明确一个消息系统的核心功能: 一个通用的事件监听器 管理各个业务监听的事件类型(注册和解绑事件监听器) 全局广播事件 广播事件所传参数数量和数据类型都是可变的(数量可以是 ...
- 使用kibana来进行ElasticSearch的信息查询检索
大家经常会听到使用ELK搭建日志管理平台.完成日志聚合检索的功能,那么这个平台到底是个什么概念,怎么搭建,怎么使用呢? ELK包括ElasticSearch(数据存储.快速查询).logstash(日 ...
- MPAndroidChart Wiki(译文)~Part 3
13. 图例 默认情况下,所有的图表都支持图例并且会自动生成.给图表设置完数据之后,图例会被绘制出来.图例通常由多个条目组成,每个条目由标签形式/形状表示. 自动生成的图例包含的条目数取决于不同颜色的 ...
- 神经病院Objective-C Runtime入院第一天——isa和Class
前言 我第一次开始重视Objective-C Runtime是从2014年11月1日,@唐巧老师在微博上发的一条微博开始. 这是sunnyxx在线下的一次分享会.会上还给了4道题目. 这4道题 ...