1. 程式人生 > >HDU3951 建立對稱局勢【博弈水題】

HDU3951 建立對稱局勢【博弈水題】

Coin Game

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<=10 9,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

題意:

給你一串有連續編號石子,首尾連成一個環(即1和N相鄰),每次可以取相鄰的1~K個石子,最後取完者勝

分析:

  1. 若先手一次可以取完(N<=K),先手必勝
  2. 若K=1,顯然N為奇數,先手必勝
  3. 若K>=2,後手只需要建立一個對稱局勢,即把這條鏈分成兩條相等的鏈,先手必敗
import java.util.*;
import java.math.*;

public class Main{
	static int MAXN=(int)(2e5+10);
	static long n;
	
	public static void main(String[] args) {
		Scanner cin=new Scanner(System.in);
		int T=cin.nextInt();
		int ca=1;
		while((T--)!=0) {
			n=cin.nextLong();
			int k=cin.nextInt();
			System.out.print("Case "+ ca++ +": ");
			if(n<=k) {
				System.out.println("first");
				continue;
			}
			if(k==1) {
				if(n%2==1)
				System.out.println("first");
				else
				System.out.println("second");
				continue;
			}
			System.out.println("second");
		}
		cin.close();
	}
}

2018年ACM-ICPC 南京現場賽 A.Adrien and Austin

題意

有一堆數量為N的石子,石子編號從1⋯N1\cdots N1⋯N排成一列,兩個人玩遊戲,每次可以取1⋯K1\cdots K1⋯K個連續編號的石子,Adrien先手,如果有誰不能取了則他輸,兩個人為Adrien 和Austin

思路

當K為1時顯然的和N的奇偶性有關,那麼我們考慮一下K>1的情況
對於先手的Adrien來說,他對任意的N顆石子,他都可以將這N顆石子分成兩段相當數量的石子(從中間開始拿對於奇數拿一顆,對於偶數拿兩顆),那麼剩下的兩段相當於是獨立的兩個相同的遊戲了,如果後手拿其中一段,那麼我先手就對另一段進行這樣相同的拆分,那麼能保證我先手總是有石子能拿,所以我先手必勝,也就是說當K>1K&gt;1K>1的時候先手必勝,K==1的時候判斷奇偶,N==0的時候特判即可

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <math.h>
#include <stack>
#include <list>
int main()
{
    int n,k;
    scanf("%d%d",&n,&k);
    if(n==0)
    {
        printf("Austin\n");
    }
    else if(k==1)
    {
        if(n%2==1)
            printf("Adrien\n");
        else
            printf("Austin\n");
    }
    else
        printf("Adrien\n");
    return 0;
}