• CF1451D Circle Game 题解


    题意分析

    给出一个半径为 $d$ 的圆,以 $(0,0)$ 为起点,每次可以向上或向右移动 $k$ 个单位,先移出圆的为败,求先手还是后手能赢。

    思路分析

    经过分析可以发现,无论对方怎么走,先手可以保证在直线 $y=x+k$ 或 $y=x-k$ 上行走,后手可以保证在直线 $y=x$ 上行走。因此,当存在一个必胜点(即下一步必定出圆) $(x,y)$ 满足 $|y-x|=k$ 且 $k|x$ ,则先手可以走到这里保证必胜;同理,当存在一个必胜点 $(x,y)$ 满足 $x=y$ 且 $k|x$ ,则后手可以走到这里保证必胜。

    具体实现

    显然我们应该首先在直线 $y=x$ 上走得尽量远,然后判断最远的点是否为必胜点,如果是则后手胜,否则先手胜。具体判断即看下一步是否会超出圆。显然最远即半径长 $d$ ,而每走 $2$ 步走的距离即为 $sqrt{2}k$ ,因此能走的最大步数为 $2left lfloor frac{d}{sqrt{2}k} ight floor$ ,此时的坐标为 $(kleft lfloor frac{d}{sqrt{2}k} ight floor,kleft lfloor frac{d}{sqrt{2}k} ight floor)$ 。下一步往上走和往右走都一样,即走到 $(kleft lfloor frac{d}{sqrt{2}k} ight floor,k(left lfloor frac{d}{sqrt{2}k} ight floor+1))$ ,用两点间的距离公式判断是否出圆即可,即最终只需要判断 $(kleft lfloor frac{d}{sqrt{2}k} ight floor)^2+(k(left lfloor frac{d}{sqrt{2}k} ight floor+1))^2>d^2$ ,若成立,则会超出,后手胜;否则先手胜。向下取整可以直接强制类型转换为整型。

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #define ll long long
    #define ld long double
    using namespace std;
    int T;
    ll d,k;
    int main()
    {
        scanf("%d",&T);
        while(T--)
        {
            scanf("%lld%lld",&d,&k);
            puts(pow(k*(ll)((ld)d/sqrt((ld)2)/k),2)+pow(k*(ll)((ld)d/sqrt((ld)2)/k+1),2)>d*d?"Utkarsh":"Ashish");
        }
        return 0;
    }
  • 相关阅读:
    【Golang】 关于Go 并发之三种线程安全的 map
    Halodoc使用 Apache Hudi 构建 Lakehouse的关键经验
    Logstash优化吞吐率
    ES集群状态yellow修复
    ES集群状态red修复
    vxetable 导出Excel 超过100条,自定义模板template替换失效
    [转]使用minio搭建自己的文件存储服务(新版和旧版)
    [转]vue 预览pdf,txt
    windows7 使用nvs升级降级node.js版本
    新建Token来访问K8S apiserver
  • 原文地址:https://www.cnblogs.com/TEoS/p/14029814.html
Copyright © 2020-2023  润新知