问题 D: 小花梨的取石子游戏

问题 D: 小花梨的取石子游戏

强调

本人是一名小弱鸡,如果有错误,请各位大佬指出。第一次写,希望大家能够提出不足之处。

题目描述

小花梨有n堆石子,第i堆石子数量为ai,n堆石子顺时针编号为1−n(如图)。
游戏将进行n轮,每轮游戏单独进行,互不干扰,每轮初始时第i堆石子数目为ai。
第i轮从编号为i的那堆石子为起点,顺时针来取石子。两人轮流取石子,不可不取,最少取一个石子,最多把当前这一堆取完,只有取完一堆后才走到下一堆石子。走完一圈后石子都被取完,不能取石子的人就失败。假设两人以最优策略进行取石子操作,请分别输出n轮游戏是先手胜还是后手胜。

输入

第一行为正整数n,表示石子的堆数(1≤n≤100000)
第二行输入n个正整数表示每一堆的石子数目ai(1≤ai≤109)

输出

输出n行,第i行表示第i轮游戏的结果。如果先手胜则输出"First",后手胜输出"Second"。

样例输入

3
2 1 3

样例输出

First
Second
First

提示

游戏进行3轮
第1轮游戏石子堆下标的顺序为1 2 3,此时石子数目按顺序为2 1 3,先手胜
第2轮游戏石子堆下标的顺序为2 3 1,此时石子数目按顺序为1 3 2,后手胜
第3轮游戏石子堆下标的顺序为3 1 2,此时石子数目按顺序为3 2 1,先手胜

解题思路:这道题一开始让我思考了很久,但是多设计几组样例就可以总结出一个规律出来。

1.从任意一堆开始拿,只要开始的这一堆不是1,就对于先手来说一定是必胜态,即一定是先手必胜。

证明:假设从第i堆开始拿,对于剩下的n-1堆来说,双方都执行最优解,假设是后手必胜,,那么只要先手的一方在第i堆的时候拿a[i]个,那么后手的那一方在剩下的n-1堆中就变为了先手,即对于所有的n堆是先手必胜。再假设对于剩下的n-1堆先手必胜,那么只要先手的一方在第i堆是拿a[i]-1个,那么对于剩下的n-1堆来说,第i堆的先手方变成了后手方,即对于所有的n堆来说 还是先手必胜。综上所述,知道开始拿的第i堆不是1个,就一定是先手必胜。

2.假设第i堆中只有一个石头,那么对于游戏双方,先手的那方是没有什么操作空间的,他只能够拿走那一个石头,那么对于剩下未拿的石头堆来说,先后手双方交替了。假设所有的石头堆都只有一个石头,那么双方对于每一堆石头都只能一次性全部拿光,即从第i堆开始拿到第j堆后,双方的先后手权力交换了j-i次,如果交换的次数为偶数的话,那么相当于先手权没有发生交换,如果是奇数,相当于先手权发生交换。那么对于剩下的石头堆就可以变为第一种情况,即先手必胜。

下列是AC代码

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
const int N=100000;
int a[N+5];
int b[2*N+5];
int main()
{
    int x,flag=0;
    cin>>x;
    for(int i=0;i<x;i++)
    {
        scanf("%d",&a[i]);
        a[i+x]=a[i];
        if(a[i]!=1) flag=1;
    }
    for(int j=2*x-1;j>=0;j--)
    {
        if(a[j]==1) b[j]=b[j+1]+1;
        else b[j]=0;
    }
    for(int i=0;i<x;i++)
    {
        if(flag==0)
        {
            if(x%2==0) printf("Second\n");
            else printf("First\n");
        }
        else
        {
            if(a[i]!=1) printf("First\n");
            else
            {
                if(b[i]%2!=0) printf("Second\n");
                else printf("First\n");
            }
        }
    }
    return 0;
}*
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值