ZOJ 2593 One Person Game(扩展欧几里德、|x| + |y|最小)

原创 2016年05月31日 01:08:32

题目链接:
ZOJ 2593 One Person Game
题意:
有两个点A,B,每次可以选择向左或向右走a,b,c(c = a + b)步,问最少需要多少次从A走向B?
分析:
假设走a步和走b步的次数各为x,y,则可以得到:A + x * a + b * y = B.可以利用扩展欧几里德求出这个二元一次不定方程的一组基础解。我们需要的是C = |x| + |y|的最小值。当x,y符号相同时可以利用一次走c步得到应是取max(abs(x), abs(y)).当x,y符号相异时就应该取abs(x) + abs(y).但是显然x, y有无数组解,那么哪组解答案是最优的呢?
假设基础解为(x0, y0),那么通解可以表示为:x = x0 + k * b, y = y0 - k * a(k ∈ Z)。
如果令x = 0得:k = -x0 / b…①,令y = 0得:k = y0 / a…②当两者同时满足并根据分数的性质:a / b = c / d = (a + c) / (b + d)可得: k = (y0 - x0) / (b + a),但是考虑到这个数的真实值可能为浮点数,需要左右考虑。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <climits>
#include <cmath>
#include <ctime>
#include <cassert>
#define IOS ios_base::sync_with_stdio(0); cin.tie(0);
using namespace std;
typedef long long ll;

int T;

ll ex_gcd(ll a, ll b, ll& x, ll& y)
{
    if(b == 0) {
        x = 1, y = 0;
        return a;
    }
    ll d = ex_gcd(b, a % b, y, x);
    y -= a / b * x;
    return d;
}

ll solve(ll a, ll b, ll t)
{
    ll x, y, d, res;
    d = ex_gcd(a, b, x, y);
    if(t % d) return -1;
    a /= d, b /= d, t /= d;
    x *= t, y *= t;
    res = (ll)1e18;
    ll tmpx, tmpy, c = (y - x) / (a + b);
    for(int i = c - 1; i <= c + 1; i++){
        tmpx = x + i * b, tmpy = y - i * a;
        if(tmpx * tmpy >= 0) res = min(res, max(abs(tmpx), abs(tmpy)));
        else res = min(res, abs(tmpx) + abs(tmpy));
    }
    return res;
}

int main()
{
    ll a, b, A, B;
    scanf("%d", &T);
    while(T--){
        scanf("%lld%lld%lld%lld", &A, &B, &a, &b);
        printf("%lld\n", solve(a, b, abs(B - A))); 
    }
    return 0;
版权声明:缥缈玉京人,想语然、京兆眉妩。

ZOJ3329 One Person Game

题目大意: 有三个骰子,分别有K1,K2,K3个面,一次投掷可以得到三个骰子点数加和的分数,但是,当骰子1等于A,骰子2=B,骰子3=C时,结果清零。问从0开始,分数超过N时投掷次数的期望。 ...
  • noip_2009
  • noip_2009
  • 2014年08月13日 18:59
  • 434

ZOJ - 3593 One Person Game (扩展欧几里得 技巧)@

There is an interesting and simple one person game. Suppose there is a number axis under your feet. ...
  • yjf3151731373
  • yjf3151731373
  • 2017年04月15日 09:28
  • 235

zoj-3329-One Person Game-有环的概率DP

感觉kuangbin写的题解不错,就直接抄袭过来啦。。。 地址:http://www.cnblogs.com/kuangbin/archive/2012/10/03/2710648.html 题意...
  • rowanhaoa
  • rowanhaoa
  • 2014年06月24日 15:31
  • 855

ZOJ - 3593 One Person Game (扩展欧几里德)

One Person Game Time Limit: 2 Seconds      Memory Limit: 65536 KB There is an interesting and ...
  • HHH_go_
  • HHH_go_
  • 2017年07月24日 23:21
  • 161

One Person Game(zoj3593+扩展欧几里德)

One Person Game Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu Submit S...
  • u010579068
  • u010579068
  • 2015年05月04日 22:20
  • 1121

ZOJ One Person Game

对期望仍然理解的不深入啊#include #include #include using namespace std; #define MAXN 505 double f[MAXN][2];...
  • whosemario
  • whosemario
  • 2011年04月14日 09:30
  • 467

One Person Game(ZOJ3329)

题目链接:http://icpc.moe/onlinejudge/showProblem.do?problemCode=3329 题目意思是,给三个骰子,骰子分别有K1,K2,K3个面,另外设定a,...
  • tinyguyyy
  • tinyguyyy
  • 2016年04月05日 18:35
  • 313

ZOJ 3329 One Person Game(概率问题)

转载请注明出处,谢谢http://blog.csdn.net/acm_cxlove/article/details/7854526       by---cxlove 题目:有3个筛子,分别有k...
  • ACM_cxlove
  • ACM_cxlove
  • 2012年08月30日 19:32
  • 2262

One Person Game ZOJ - 3593

题目传送门题意:给你一个起点A和终点B,你可以一次向前行进或者向后行进a,b,(a + b)米,问你最少多少次能够到达终点。思路:直接扩展欧几里得,然后求出来通解以后再去求出来最优的通解就可以了。#i...
  • GoneWithTheWind_yin
  • GoneWithTheWind_yin
  • 2017年09月22日 11:48
  • 58

zoj 3329 One Person Game

题目链接:zoj 3329 One Person Game 这个题目的思维太巧了,题意就不讲了  E[ i ] = ∑pk * E[i + k] + E[0] * p[0]  而 E[0 ...
  • struggle_mind
  • struggle_mind
  • 2012年09月27日 14:18
  • 487
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:ZOJ 2593 One Person Game(扩展欧几里德、|x| + |y|最小)
举报原因:
原因补充:

(最多只允许输入30个字)