您的位置:首页 > 其它

UVALive-7278 - Game of Cards【博弈】【sg定理】

2016-08-06 18:11 441 查看

UVALive-7278 - Game of Cards





题目大意:A、B两个人玩游戏。A先手,问最后谁赢。

游戏规则:

给出n堆纸牌,可任意选择其中一堆,记为x

在x的顶部可取走[0,k]张纸牌,该堆纸牌至少留下一张

x剩下来的纸牌中,记顶部的纸牌值为y,则移除最顶部的y张纸牌(即该堆至少还剩下y张纸牌才是合法)

如果有人不能进行合法移动,则输了。

题目思路:主要是写SG函数,每一堆的sg函数都不同。最后每一堆 ans ^= sg
,即可。

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
;
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  SG定理 博弈 UVALive 7278