Game of Cards Gym

Problem G: Game of Cards

[Time Limit: 1 s quad Memory Limit: 256 MiB ]

题意

题意就是给出(n)堆扑克牌,然后给出一个(m),每次一个人的操作方法是从一堆扑克牌上面选出(0-m)张牌拿开,然后此时顶上牌的点数是(x),在拿开(x)张牌,最后不能操作的人输。

思路

就是一个裸的(sg)函数,用dfs比较好写,然后直接模拟就可以了。

/***************************************************************
    > File Name    : G.cpp
    > Author       : Jiaaaaaaaqi
    > Created Time : 2019年05月06日 星期一 18时04分27秒
 ***************************************************************/

#include <map>
#include <set>
#include <list>
#include <ctime>
#include <cmath>
#include <stack>
#include <queue>
#include <cfloat>
#include <string>
#include <vector>
#include <cstdio>
#include <bitset>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define  lowbit(x)  x & (-x)
#define  mes(a, b)  memset(a, b, sizeof a)
#define  fi         first
#define  se         second
#define  pii        pair<int, int>
#define  INOPEN     freopen("in.txt", "r", stdin)
#define  OUTOPEN    freopen("out.txt", "w", stdout)

typedef unsigned long long int ull;
typedef long long int ll;
const int    maxn = 1e3 + 10;
const int    maxm = 1e5 + 10;
const ll     mod  = 1e9 + 7;
const ll     INF  = 1e18 + 100;
const int    inf  = 0x3f3f3f3f;
const double pi   = acos(-1.0);
const double eps  = 1e-8;
using namespace std;

int n, m, k;
int cas, tol, T;

int a[maxn];
ll sg[maxn];

void dfs(int x) {
	if(sg[x] != -1)	return ;
	vector<bool> vis(maxn, false);
	for(int i=0; i<=m; i++) {
		int up = x-i;
		if(up <= 0)	break;
		int nxt = up - a[up];
		if(nxt < 0)	continue;
		dfs(nxt);
		vis[sg[nxt]] = true;
	}
	for(int i=0; ; i++) {
		if(!vis[i]) {
			sg[x] = i;
			return ;
		}
	}
}

int main() {
	scanf("%d%d", &T, &m);
	ll ans = 0;
	while(T--) {
		scanf("%d", &n);
		mes(a, 0);
		mes(sg, -1);
		a[0] = sg[0] = 0;
		for(int i=1; i<=n; i++) {
			scanf("%d", &a[i]);
		}
		dfs(n);
		ans ^= sg[n];
	}
	if(ans)	
		printf("Alice can win.
");
	else	
		printf("Bob will win.
");
	return 0;
}
原文地址:https://www.cnblogs.com/Jiaaaaaaaqi/p/10821180.html