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;
    }
    
  • 相关阅读:
    干货:分布式系统详解
    如果有人问你数据库的原理,叫他看这篇文章
    MySQL的B树索引与索引优化
    优化网站性能必备的6种架构方案,你知道吗?
    【干货】手把手教你搭建一套可自动化构建的微服务框架
    你真的理解微服务架构吗
    Android Activity 半透明效果(Translucent)
    Android DatepickerDialog(日期选择器)的使用
    Android搜索自动提示功能 AutocompleteTextView
    Android动态加载ListView中的Item
  • 原文地址:https://www.cnblogs.com/lrj124/p/13509138.html
Copyright © 2011-2022 走看看