Coin Game HDU-3951 Game theory NP reasoning, using the symmetry of mirroring

  • First, for a situation: n ≤ kn\le knWhen k is the first to win, you can take all one step.
  • When k = 1 k=1k=At 1 , ifnnIf n is an odd number, the first mover will win, which isNNN points; ifnnIf n is an even number, the first move must be defeated, which isPPP point.
  • For the remaining cases, you need to use the mirror principle to explore. First of all, for the first hand, after taking any stone, the second hand can be selected according to the parity of the number of remaining stones to ensure that the resulting two pieces are symmetrical.
  • The title means that only continuous fragments can be taken, so in the above, it was originally a circular shape. After the first hand is taken, an arc is formed, and then the second hand divides the arc into two identical pieces: If the first hand is taken, the arc is formed. If the number of stones remaining is an odd number, then 1 1 will be taken from the back hand1 stone, so that the arc forms two identical arcs; otherwise, if the number of stones remaining after the first hand is taken is an even number, then the second hand takes2 2Two stones form two identical arcs.
  • After forming two identical arcs, in the next round, no matter which side the first hand takes, the second hand will choose the opposite one to take exactly the same method, which can ensure that the second hand will win.
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uii;
typedef pair<int, ll> pii;
template<typename T>
inline void rd(T& x)
{
    
    
	int tmp = 1; char c = getchar(); x = 0;
	while (c > '9' || c < '0') {
    
     if (c == '-')tmp = -1; c = getchar(); }
	while (c >= '0' && c <= '9') {
    
     x = x * 10 + c - '0'; c = getchar(); }
	x *= tmp;
}
const int N = 2e5 + 10;
const int M = 1e7 + 10;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
int n, m, k;
int main() {
    
    
#ifdef _DEBUG
	FILE* _INPUT = freopen("input.txt", "r", stdin);
	//	FILE* _OUTPUT = freopen("output.txt", "w", stdout);
#endif // !_DEBUG
	int cas = 0, T = 0;
	rd(T);
	while (T--) {
    
    
		//	while (~scanf("%d", &n),~n) {
    
    
		rd(n), rd(k);
		printf("Case %d: ", ++cas);
		if (n <= k) puts("first");
		else if (k == 1) {
    
    
			if (n & 1) puts("first");
			else puts("second");
		}
		else puts("second");
	}
	return 0;
}

Guess you like

Origin blog.csdn.net/bloom_er/article/details/113775103