虽然题目有一点变形,不过本质还是用SG函数,nim(n)=mex{nim(n-s[i])},想清楚这一点,问题就比较容易解决了。
分析:
1.可将问题转化为n个子问题,每个子问题分别为:
从一堆x颗石子中取石子,每次可取的石子数为集合S(k)中的一个数
2.分析(1)中的每个子问题,
易得:SG(x) = mex(SG[x-s[i]])(0<i<k-1);
3.后面就是SG函数的应用,根据Sprague-Grundy Therem:g(G)=g(G1)^g(G2)^g(G3)^...^g(Gn)
即游戏的和的SG函数值是它的所有子游戏的SG函数值的异或,即
SG(G) = SG(x1)^SG(x2)^...^SG(xn),故若SG(G)=0那么必输
#include<iostream>
using namespace std;
int main(){
int t,m,number,goal[10005],s[105],tmp,mark[10005];
while(cin>>t&&t){
for(int i=0;i<t;i++)
cin>>s[i];
goal[0]=0;
for(int i=0;i<10005;i++)
mark[i]=9999999;
for(int i=1;i<=10000;i++){
for(int j=0;j<t;j++){
if(i>=s[j]){
mark[goal[i-s[j]]]=i;
}
}
goal[i]=0;
while(mark[goal[i]]==i)
goal[i]++;
}
cin>>m;
for(int i=0;i<m;i++){
cin>>number;
int sum=0;
for(int j=0;j<number;j++){
cin>>tmp;
sum=sum^goal[tmp];
}
if(sum==0)
cout<<"L";
else cout<<"W";
}
cout<<endl;
}
return 0;
}