题意:有n堆石头,每堆石头的个数已知,两人轮流从中取石头,每次取石头的个数来自集合S,问先拿者是否有必胜策略
思路:SG定理的应用,SG[i]=i(Nim博弈),先求出所有的SG值,贮存在数组中(可以与HDU 1848对比)
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int s[101];
int k;
int sg[10050];
int vis[10050];
void getsg()
{
int i;
for(int x=0;x<=10000;x++){
memset(vis,0,(x+1)*sizeof(int));
for(i=0;i<k;i++){
if(s[i]>x)break;
vis[sg[x-s[i]]]=1;
}
for(i=0;vis[i];i++);
sg[x]=i;
}
}
int main()
{
int i;
while(scanf("%d",&k)==1&&k){
for(i=0;i<k;i++)
scanf("%d",&s[i]);
sort(s,s+k);
getsg();
int n,T,ans;
scanf("%d",&T);
while(T--){
ans=0;
scanf("%d",&n);
while(n--){
scanf("%d",&i);
ans^=sg[i];
}
printf("%c",ans==0?'L':'W');
}
printf("\n");
}
}

本文介绍了一个关于石头博弈的问题,通过SG定理来寻找先手玩家是否有必胜策略。利用C++代码实现算法,包括输入石头堆数量、每堆石头的数量,以及可能取出石头的集合S等步骤。
&spm=1001.2101.3001.5002&articleId=77200007&d=1&t=3&u=3ceaf8185b01469b8025cfdff9dc336f)

被折叠的 条评论
为什么被折叠?



