ZOJ 3593 One Person Game (扩展欧几里得)
来源:互联网 发布:union软件安卓版 编辑:程序博客网 时间:2024/04/30 04:47
There is an interesting and simple one person game. Suppose there is a number axis under your feet. You are at pointA 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 bya,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 integersA, 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 pointB, output "-1" instead.
Sample Input
20 1 1 20 1 2 4
Sample Output
1-1
题意是在数轴上给出两个点 再给你能走的距离 a, b, a+b (向左或向右都可以), 问最少需要多少步可以从一个点走到另一个点。不能到达输出-1
此题是扩展欧几里得问题。
我们可以设 走了x步a,走了y步b, ax + by = |A-B|, 扩展欧几里得解出x和y就是可行答案 但不一定是最少的步数。
现在可以假设如果x和y都是正的,也就是说不往回走,这样可以利用题目给的a+b步数进行优化,不管怎么样结果是x和y的较大值,那么假设x = y, 如果x减小,那么y一定增大 因为总路程是不变的,y减小同理,因此可以认为 x = y的时候 两者的较大值最小。
假设x小于0,y大于0,也就是x步往回走,y步正向走。那么这个结果就是abs(x) + abs(y),如果x继续减小说明往回走的多了 相应的y应该增大 那么最后的结果是增大的。
也就是说 x要尽量的增大 y要尽量的减小,可以理解为x与y最接近的时候取得最小步数。
综上两种情况 (x大于0 y小于0 类似第二种) 可以得到最小值的取得在 x == y 处。 但是可能这个点不存在,就要取他的附近两个点作比较,因为扩展欧几里得的特解求出之后 通解是可以求出的。
#include <algorithm>#include <iostream>#include <sstream>#include <cstring>#include <cstdlib>#include <cstdio>#include <vector>#include <cmath>#include <queue>#include <set>#include <map>#define mod 4294967296#define MAX 0x3f3f3f3f#define lson o<<1, l, m#define rson o<<1|1, m+1, r#define INFL 0x3f3f3f3f3f3f3f3fLL#define mem(a) memset(a, 0, sizeof(a))const double pi = acos(-1.0);const double eps = 1e-9;const int N = 10005;typedef long long ll;using namespace std;ll a, b, st, en;void exgcd(ll a, ll b, ll& d, ll& x, ll& y) { if(!b) { d = a; x = 1; y = 0; } else { exgcd(b, a%b, d, y, x); y -= x*(a/b); }}ll cal(ll x, ll y) { if(x * y > 0) return max(abs(x), abs(y)); else return abs(x) + abs(y);}int main() { //freopen("in.txt", "r", stdin); int T; cin >> T; while(T--) { cin >> st >> en >> a >> b; ll len = abs(st-en); ll d, x, y; exgcd(a, b, d, x, y); if(len % d) { puts("-1"); continue; } x = x*len/d; y = y*len/d; ll t = (y-x)/(a/d + b/d); ll ans = cal(x + t * (b/d), y - t * (a/d)); ans = min(ans, cal(x + (t+1) * (b/d), y - (t+1) * (a/d))); ans = min(ans, cal(x + (t-1) * (b/d), y - (t-1) * (a/d))); cout << ans << endl; } return 0;}
- zoj 3593 One Person Game 扩展欧几里得
- ZOJ 3593 One Person Game (扩展欧几里得)
- ZOJ 3593.One Person Game 扩展欧几里得+逼近
- zoj 3593 One Person Game(扩展gcd)
- ZOJ 3593 One Person Game 【带简单处理的扩展欧几里得】
- 【数论(扩展的欧几里德)】ZOJ-3593-One Person Game
- ZOJ 3593 One Person Game
- ZOJ-3593 One Person Game
- ZOJ 3593 One Person Game
- ZOJ 3593.One Person Game【扩展欧几里得+逼近】【4月11】
- ZOJ One Person Game
- One Person Game ZOJ
- One Person Game ZOJ
- ZOJ 3329 One Person Game(1)
- ZOJ 2593 One Person Game(扩展欧几里德、|x| + |y|最小)
- zoj 3329 One Person Game
- ZOJ 3329 One Person Game
- ZOJ 3329 One Person Game
- jsp技术
- XAMPP for MAC 安装后MYSQL不能正常启动的解决办法
- vs2012编译使用lua 5.2静态库
- Intent 传递中 Bundle与intent.putExtra 的关系
- 牡丹江的水题们
- ZOJ 3593 One Person Game (扩展欧几里得)
- linux下安装nginx
- Leetcode 74 Search a 2D Matrix 有序二维数组二叉查找
- Spring3学习笔记之(spring core之DI配置使用1)
- CSU 1607: Do You Have The Template?(树链剖分)边权
- 整理牛人看文献的方法
- 研究生、科研人员须知的文献管理软件及一个学术会议网站
- Git 命令速查手册
- cocos2dx 3.2在Eclipse上打包出现error: call of overloaded 'abs(float)' is ambiguous