zoukankan      html  css  js  c++  java
  • 20200922day18 刷题记录

    1 跳跳棋

    题面

    跳跳棋是在一条数轴上进行的。棋子只能摆在整点上。每个点不能摆超过一个棋子。我们用跳跳棋来做一个简单的游戏:棋盘上有三颗棋子,分别在 (a,b,c) 这三个位置。我们要通过最少的跳动把他们的位置移动成 (x,y,z)

    (注意:棋子是没有区别的)。

    跳动的规则很简单,任意选一颗棋子,对一颗中轴棋子跳动。跳动后两颗棋子距离不变。一次只允许跳过一颗棋子。

    写一个程序,首先判断是否可以完成任务。如果可以,输出最少需要的跳动次数。

    样例输入

        1 2 3
        0 3 5
    

    样例输出

        YES
        2
    

    题解

    代码

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define int long long
    using namespace std;
    
    int read() {
        int a = 0, x = 1;
        char ch = getchar();
        while (ch > '9' || ch < '0') {
            if (ch == '-')
                x = -1;
            ch = getchar();
        }
        while (ch >= '0' && ch <= '9') {
            a = a * 10 + ch - '0';
            ch = getchar();
        }
        return a * x;
    }
    struct node {
        int a[4];
        friend bool operator!=(node a, node b) {
            for (int i = 1; i <= 3; i++)
                if (a.a[i] != b.a[i])
                    return true;
            return false;
        }
        friend bool operator==(node a, node b) { return !(a != b); }
        void print() { printf("%lld %lld %lld
    ", a[1], a[2], a[3]); }
    } A, B;
    const int inf = 1e18;
    node r1, r2;
    int temp = 0, dep1, dep2;
    node find(node S, int k) {
        int z1 = S.a[2] - S.a[1], z2 = S.a[3] - S.a[2], tmp;
        if (z1 > z2) {
            tmp = min((z1 - 1) / z2, k);
            z1 -= tmp * z2;
            temp += tmp;
            k -= tmp;
            S.a[2] -= tmp * z2, S.a[3] -= tmp * z2;
        } else if (z1 < z2) {
            tmp = min((z2 - 1) / z1, k);
            z2 -= tmp * z2;
            k -= tmp;
            temp += tmp;
            S.a[1] += tmp * z1, S.a[2] += tmp * z1;
        }
        if (z1 == z2)
            return S;
        if (k)
            return find(S, k);
        return S;
    }
    
    signed main() {
        for (int i = 1; i <= 3; i++) A.a[i] = read();
        for (int i = 1; i <= 3; i++) B.a[i] = read();
        sort(A.a + 1, A.a + 4);
        sort(B.a + 1, B.a + 4);
        r1 = find(A, inf);
        dep1 = temp, temp = 0;
        r2 = find(B, inf);
        dep2 = temp, temp = 0;
        if (r1 != r2) {
            printf("NO");
            return 0;
        }
        if (dep1 < dep2) {
            swap(dep1, dep2);
            swap(A, B);
        }
        A = find(A, dep1 - dep2);
        int l = 0, r = dep2, mid;
        while (l != r) {
            mid = l + r >> 1;
            if (find(A, mid) == find(B, mid))
                r = mid;
            else
                l = mid + 1;
        }
        printf("YES
    %lld", l * 2 + (dep1 - dep2));
        return 0;
    }
    
    要做就做南波万
  • 相关阅读:
    前端学习之——h5适配
    Python学习之——【开始】
    前端学习之----隐式类型转换
    前端学习之----数据类型
    vue学习之——生命周期
    认识自己(一)
    判断一句话是否是回文,例如, 上海自来水来自海海上
    判断是否为质数
    Python之函数进阶
    Python之冒泡排序
  • 原文地址:https://www.cnblogs.com/liuziwen0224/p/20200922day18-001.html
Copyright © 2011-2022 走看看