UVALive-7278 - Game of Cards
题目大意:A、B两个人玩游戏。A先手,问最后谁赢。
游戏规则:
- 给出n堆纸牌,可任意选择其中一堆,记为x
- 在x的顶部可取走[0,k]张纸牌,该堆纸牌至少留下一张
- x剩下来的纸牌中,记顶部的纸牌值为y,则移除最顶部的y张纸牌(即该堆至少还剩下y张纸牌才是合法)
如果有人不能进行合法移动,则输了。
题目思路:主要是写SG函数,每一堆的sg函数都不同。最后每一堆 ans ^= sg[n],即可。
SG函数详见代码。
以下是代码:
#include <iostream>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <functional>
#include <numeric>
#include <string>
#include <set>
#include <map>
#include <stack>
#include <vector>
#include <queue>
#include <deque>
#include <list>
using namespace std;
int k;
int num[10005];
int sg[10005];
void sg_solve(int N)
{
int i,j;
bool hash[N];
memset(sg,0,sizeof(sg));
for (i = 1; i <= N; i++) //第i这个状态
{
memset(hash,0,sizeof(hash));
for (j = 0; j <= k; j++) //遍历所有可走的状态,每次可以取走[0,k]张
{
if (i - j <= 0) continue;
int bu = j + num[i - j]; //取走j张牌,还要加上对应的最后一张牌的值(因为还要移除这么多张牌)
if (i - bu >= 0)
{
hash[sg[i - bu]] = 1;
}
}
for (j = 0; j < N; j++)
{
if (!hash[j]){ sg[i] = j; break; }
}
}
}
int main()
{
int p;
while(cin >> p >> k)
{
int ans = 0;
while(p--)
{
int t;
cin >> t;
memset(num,0,sizeof(num));
for (int i = 1; i <= t; i++)
{
cin >> num[i];
}
sg_solve(t + 10);
ans ^= sg[t];
}
if (ans) cout << "Alice can win.\n";
else cout << "Bob will win.\n";
}
return 0;
}
时间: 2024-10-03 20:08:10