zoukankan      html  css  js  c++  java
  • 【AGC002E】 Candy Piles

    题目大意

    桌上有 N 堆糖果,第 i 堆糖果有Ai 个糖。两人在玩游戏,轮流进行,每次进行下列两个操作中的一个

    1. 将当前最大的那堆糖果全部吃完

    2. 将每堆糖果吃掉一个

    吃完的人输,假设两人足够聪明,问谁能必胜 1<=n<=10^5 1<=ai<=10^9

    输出 First(表示第一个人必胜),或 Second(表示第二个人必胜

    思路

    可以把糖果降序排序,转换成 n 列网格,每列的高度为每堆的数量,如下图所示

    起点从 (1,1) 开始,操作 1 可转换为向右走一格,操作 2 可转换为向上走一格,当走到边界时即为吃完所有糖果

    所以可以得到边界的点都为必败点,若一个点上面或右边有必胜点这个点一定为必败点(对手一定会走到必胜点),否则为必胜

    若 (1,1) 为必败点则先手必胜(可看为后手操作到了 (1,1),所以 (1,1) 是后手的胜负状态),反之亦然

    然后仔细观察发现同一条对角线上的点胜负状态一定相同,所以可以计算对角线上最后一个点的胜负来判断起点的胜负

    然后找规律,若对角线上最后一个点到最上面或到最右边的距离有奇数,这个点即为必败点

    /************************************************
    *Author        :  lrj124
    *Created Time  :  2020.08.14.11:48
    *Mail          :  1584634848@qq.com
    *Problem       :  at1999
    ************************************************/
    #include <algorithm>
    #include <iostream>
    #include <cstdio>
    using namespace std;
    const int maxn = 1e5 + 10;
    int n,a[maxn];
    int main() {
    //	freopen("at1999.in","r",stdin);
    //	freopen("at1999.out","w",stdout);
    	scanf("%d",&n);
    	for (int i = 1;i <= n;i++) scanf("%d",&a[i]);
    	sort(a+1,a+n+1,greater<int>());
    	for (int i = 1;i <= n;i++)
    		if (i >= a[i+1]) {
    			int cnt = 0;
    			for (int j = i+1;j <= n;j++) if (a[j] == i) cnt++; else break;
    			return puts((a[i]-i)&1 || cnt&1 ? "First" : "Second"),0;
    		}
    	return 0;
    }
    
  • 相关阅读:
    下载安装包,安装PySide2到windows系统
    Qt5 中关于信号槽 SIGNALS/SLOTS的改动
    软件产品线、MVC、MVP
    UML序列图总结
    浅谈UML中常用的几种图
    docker安装gitlab-ce镜像,使用其他端口
    git在linux下的安装和使用
    服务注册中心Eureka Server的简单配置、访问控制配置以及高可用配置
    让你远离sql语句的Mybatis工具:Tkmybatis
    tk mybatis update 各种类型
  • 原文地址:https://www.cnblogs.com/lrj124/p/13509138.html
Copyright © 2011-2022 走看看