【hdu 3951】Coin Game

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1851 Accepted Submission(s): 1065

Problem Description
After hh has learned how to play Nim game, he begins to try another coin game which seems much easier.

The game goes like this:
Two players start the game with a circle of n coins.
They take coins from the circle in turn and every time they could take 1~K continuous coins.
(imagining that ten coins numbered from 1 to 10 and K equal to 3, since 1 and 10 are continuous, you could take away the continuous 10 , 1 , 2 , but if 2 was taken away, you couldn’t take 1, 3, 4, because 1 and 3 aren’t continuous)
The player who takes the last coin wins the game.
Suppose that those two players always take the best moves and never make mistakes.
Your job is to find out who will definitely win the game.

Input
The first line is a number T(1<=T<=100), represents the number of case. The next T blocks follow each indicates a case.
Each case contains two integers N(3<=N<=109,1<=K<=10).

Output
For each case, output the number of case and the winner “first” or “second”.(as shown in the sample output)

Sample Input
2
3 1
3 2

Sample Output
Case 1: first
Case 2: second

【题目链接】:http://acm.hdu.edu.cn/showproblem.php?pid=3951

【题解】

会发现如果k!=1
先手不管怎样选一段;
我们总能在这n个硬币所围成的对角线上选取同样的一段(或者比它多一个或少一个->n为奇数的情况);这样就分成了两段硬币;
这两段硬币的个数相同;
->如果对应两个游戏的话,对应的sg函数必然是相同的;
则sg[x]^sg[x]==0
所以先手输;
我们总能让第一个人面对这种情况;
所以第一个人总是输的;
但是k=1的时候就不一定可以;
只有当n为偶数的时候第一个人输;n为奇数的话第一个人无论如何都会赢的.

【完整代码】

#include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define rei(x) scanf("%d",&x)
#define rel(x) scanf("%I64d",&x)

typedef pair<int,int> pii;
typedef pair<LL,LL> pll;

//const int MAXN = x;
const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
const double pi = acos(-1.0);

int T;

int main()
{
    //freopen("F:\\rush.txt","r",stdin);
    rei(T);
    rep1(ii,1,T)
    {
        int n,k;
        rei(n);rei(k);
        printf("Case %d: ",ii);
        if (k>=n || (k==1 && n&1))
            puts("first");
        else
            puts("second");
    }
    return 0;
}

转载于:https://www.cnblogs.com/AWCXV/p/7626730.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值