hud 1846 Bash game (simple solution or Sprague-Grundy solution)

What's the first game you're brave enough to play? Very simple, it is defined as follows:
1. This game is a two-player game;
2. There are n stones in a pile;
3. Two people take turns;
4. Each step can take away 1...m stones;
5. The side that takes all the stones first wins;

If both players in the game are using the optimal strategy, please output which one can win.

Input
The input data first contains a positive integer C (C<=100), indicating that there are C sets of test data.
Each set of test data occupies one line and contains two integers n and m (1<=n, m<=1000). The meanings of n and m are described in the title.

Output
If the person who goes first wins, please output "first", otherwise please output "second", and the output of each instance occupies one line.

Sample Input
2
23 2
4 3
ideas:

1. When n <= m, the first player can directly take the first player to win.

2. When n = m+1, the first player must lose.

using namespace std;

int main()
{
    int T,n,m;
    cin>>T;
    while(T--){
        cin>>n>>m;  
        if(n %(m-1) == 0) printf("second\n");
        else  printf("first\n");
    }
}

Solution with graph game and Sprague-Grundy function:

The rule of the graph game is to stipulate a directed acyclic graph, put a chess piece on a starting point, and two players alternately move the chess piece along the directed edge, and the player who cannot move will be judged as loser.

   x represents the number of stones, when the number of stones is 0, the first hand is a state of defeat (the first hand refers to the person who is currently taking the stone), and the back and forth are recursive.

#define _CRT_SECURE_NO_WARNINGS 1	
#include<iostream>
using namespace std;
const int MAX = 1001;
int n, m, sg[MAX], s[MAX];
void getSG() {
	memset(sg, 0, sizeof(sg));
	for (int i = 1; i <= n; i++) {
		memset(s, 0, sizeof(s));
		for (int j = 1; j <= m && i - j >= 0; j++) {
			s[sg[i - j]] = 1;
		}
		for (int j = 0; j <= n; j++) {
			if (!s[j]) {
				sg[i] = j;
				break;
			}
		}
	}
}
int main() {
	int c;
	cin >> c;
	while (c--) {
		cin >> n >> m;
		getSG();
		if (sg[n]) cout << "first" << endl;
		else cout << "second" << endl;
	}
	return 0;
}

Guess you like

Origin blog.csdn.net/zhi6fui/article/details/128706050