HDU 5795 A Simple Nim (博弈) ---2016杭电多校联合第六场

A Simple Nim

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 79    Accepted Submission(s): 48

Problem Description

Two players take turns picking candies from n heaps,the player who picks the last one will win the game.On each turn they can pick any number of candies which come from the same heap(picking no candy is not allowed).To make the game more interesting,players can separate one heap into three smaller heaps(no empty heaps)instead of the picking operation.Please find out which player will win the game if each of them never make mistakes.

Input

Intput contains multiple test cases. The first line is an integer 1≤T≤100, the number of test cases. Each case begins with an integer n, indicating the number of the heaps, the next line contains N integers s[0],s[1],....,s[n−1], representing heaps with s[0],s[1],...,s[n−1] objects respectively.(1≤n≤106,1≤s[i]≤109)

Output

For each test case,output a line whick contains either"First player wins."or"Second player wins".

Sample Input

2
2
4 4
3
1 2 4

Sample Output

Second player wins.
First player wins.

Author

UESTC

Source

2016 Multi-University Training Contest 6

Recommend

wange2014

题意:给定n堆石子,每次有两种操作,1是从任意一堆中取任意个,2是把一堆分为三堆且这三堆都不为空,问谁能赢。

题解:首先看题目的数据范围是1e9,那么算出每个sg肯定会超时,所以我们想到打表找规律。首先我们暴力打表算出200以内的sg函数值,对于一堆石子来说处理出他的所有后继情况。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int sg[10005]= {0};
bool vis[10005];
int t,cas=1;
void get()
{
    memset(sg,0,sizeof(sg));
    sg[0]=0;
    for(int i=1; i<=200; i++)
    {
        memset(vis,0,sizeof(vis));
        for(int j=1;j<=i;j++)
        {
            for(int k=1;j+k<=i;k++)
            {
                if(j!=0&&k!=0&&((i-j-k)!=0))
                vis[sg[j]^sg[k]^sg[i-j-k]]=1;//操作1
            }
        }
        for(int j=0;j<i;j++)//操作2
        vis[sg[j]]=1;
        for(int x=0; ; x++)
            if(!vis[x])
                {
                    sg[i]=x;
                    break;
                }
    }
}
int main()
{
    get();
    for(int i=1;i<=100;i++)
    printf("i: %d    %d\n",i,sg[i]);
    return 0;
}

运行该代码,我们会得到如下结果:

注意在这个表当中

观察结果我们可以得知,当n为8的倍数时,sg(n)=n+1; 当(n+1)为8的倍数时,sg(n)=n-1; 否则sg(n)=n;

所以我们把sg值异或起来就能判断出谁赢了。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n;
        long long x,ans=0;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
            scanf("%lld",&x);
            if(x%8==0)
            ans=ans^(x-1);
            else if((x+1)%8==0)
            ans=ans^(x+1);
            else
            ans=ans^x;
        }
        if(ans)
        puts("First player wins.");
        else
        puts("Second player wins.");
    }
    return 0;
}
时间: 2024-12-28 20:53:14

HDU 5795 A Simple Nim (博弈) ---2016杭电多校联合第六场的相关文章

HDU 5793 A Boring Question (费马小定理) ---2016杭电多校联合第六场

A Boring Question Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 156    Accepted Submission(s): 72 Problem Description There are an equation.∑0≤k1,k2,?km≤n∏1?j<m(kj+1kj)%1000000007=?We define t

HDU 5762 Teacher Bo (鸽笼原理) 2016杭电多校联合第三场

题目:传送门. 题意:平面上有n个点,问是否存在四个点 (A,B,C,D)(A<B,C<D,A≠CorB≠D)使得AB的横纵坐标差的绝对值的和等于CD的横纵坐标差的绝对值的和,n<10^5,点的坐标值m<10^5. 题解:表面上这道题复杂度是O(n^2)会超时的,而实际上这些坐标差绝对值的和最大是2*10^5,所以复杂度不是O(n^2),而是O(min(n^2,m)),这就是著名的鸽笼原理. #include <iostream> #include <cstdio

HDU 5752 Sqrt Bo (思维题) 2016杭电多校联合第三场

题目:传送门. 题意:一个很大的数n,最多开5次根号,问开几次根号可以得到1,如果5次还不能得到1就输出TAT. 题解:打表题,x1=1,x2=(x1+1)*(x1+1)-1,以此类推.x5是不超过long long的,判断输出即可. #include <iostream> #include <cstdio> #include <cstring> #include <cmath> using namespace std; typedef long long

HDU 5744 Keep On Movin (贪心) 2016杭电多校联合第二场

题目:传送门. 如果每个字符出现次数都是偶数, 那么答案显然就是所有数的和. 对于奇数部分, 显然需要把其他字符均匀分配给这写奇数字符. 随便计算下就好了. #include <iostream> #include <algorithm> #include <cstdio> #include <cstring> using namespace std; int main() { int T,n,a; scanf("%d",&T);

HDU 5742 It&#39;s All In The Mind (贪心) 2016杭电多校联合第二场

题目:传送门. 题意:求题目中的公式的最大值,且满足题目中的三个条件. 题解:前两个数越大越好. #include <iostream> #include <algorithm> #include <cstdio> #include <cstring> using namespace std; int gcd(int a,int b) { if(!b) return a; return gcd(b,a%b); } int main() { int t; ci

hdu 5795 A Simple Nim 博弈sg函数

A Simple Nim Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Problem Description Two players take turns picking candies from n heaps,the player who picks the last one will win the game.On each turn they can pick an

HDU 5745 La Vie en rose (DP||模拟) 2016杭电多校联合第二场

题目:传送门. 这是一道阅读理解题,正解是DP,实际上模拟就能做.pij+1 指的是 (pij)+1不是 pi(j+1),判断能否交换输出即可. #include <iostream> #include <algorithm> #include <cstdio> #include<cstring> using namespace std; int t,n; char str1[100009],str2[5009]; char tmp[5009]; int m

HDU 5734 Acperience (公式推导) 2016杭电多校联合第二场

题目:传送门. #include <iostream> #include <algorithm> #include <cstdio> #include <cstring> using namespace std; int gcd(long long a,long long b) { if(!b) return a; return gcd(b,a%b); } int a[100005]; int main() { int T,n; scanf("%d

?HDU 5795 A Simple Nim(简单Nim)

HDU 5795 A Simple Nim(简单Nim) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)   Problem Description - 题目描述 Two players take turns picking candies from n heaps,the player who picks the last one will win the game.On e