AtCoder Grand Contest 002 - Candy Piles (博弈)

J: Candy Piles

时间限制: 2 Sec   内存限制: 256 MB
提交: 131   解决: 23
[ 提交][ 状态][ 讨论版][命题人: admin]

题目描述

There are N piles of candies on the table. The piles are numbered 1 through N. At first, pile i contains ai candies.

Snuke and Ciel are playing a game. They take alternating turns. Snuke goes first. In each turn, the current player must perform one of the following two operations:

Choose a pile with the largest number of candies remaining, then eat all candies of that pile.
From each pile with one or more candies remaining, eat one candy.
The player who eats the last candy on the table, loses the game. Determine which player will win if both players play the game optimally.

Constraints
1≤N≤105
1≤ai≤109

输入

The input is given from Standard Input in the following format:

N
a1 a2 … aN

输出

If Snuke will win, print First. If Ciel will win, print Second.

样例输入

2

1 3

样例输出

First

提示

At the beginning of the game, pile 2 contains the most candies. If Snuke eats all candies of this pile, Ciel has no choice but to eat the last candy.



【博弈】

    两个操作: 一 去掉最大的那一个数,二是 所有的数都减1 

    谁取最后一个数则lose

  【思路】 

    将数字转化,从大到下排序, 变成一个棋盘, 那么 连个操作便可以看成 从左下角 向右还是上走

    图片:

    

    那么变转换成一个棋盘, 两个人下棋, 谁先下到边缘处,谁就lose,  

    右, 上变,  结果一定会出现在右上角处, 而且对于 k*k的棋盘,  两个角上的状态是一样的

    

    则对于答案, 要处理 矩阵对角上的 状态就可以了,   

    状态转换为,到上面边缘线的距离和 右边边缘线的距离 的奇偶问题;

    当都为奇数时 先手lose ,  否则先手win


 【代码实现】

/*
* Date: 4/4/2018
* Tile: UPC 组队训练一 补
* Category: 博弈
* AU: SIZ
* Attetion: 博弈 找规律
* WA:3
*/
#include <iostream>
#include <bits/stdc++.h>

const int MAXN=1e5+5;
const int INF=0x3f3f3f3f;

using namespace std;

int a[MAXN];
int cmp(int a,int b)
{
    return a>b;
}
int main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    int t=0;
    sort(a+1,a+n+1,cmp);
    for(;a[t]>=t;t++);
    t--;
    int flag=0;
    if((a[t]-t)%2==0)
    {
        int j;
        for( j=0;a[j+t]>=t;j++);
            if((j-1)%2==0)
            {
                flag=1;
            }
    }
    printf(!flag?"First\n":"Second\n");
    return 0;
}

1233

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值