HDU 1536 sg-NIM博弈类

本文介绍了一道经典的博弈论题目,通过使用Sprague-Grundy(SG)函数解决NIM游戏变种问题。文章详细解释了如何计算各状态的SG值,并利用异或运算确定胜负策略。适用于对博弈论及SG函数感兴趣的读者。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:每次可以选择n种操作,玩m次,问谁必胜。c堆,每堆数量告诉。

题意:sg—NIM系列博弈模板题

把每堆看成一个点,求该点的sg值,异或每堆sg值。

将多维转化成一维,性质与原始NIM博弈一样。

 1 // #pragma comment(linker, "/STACK:1024000000,1024000000")
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <sstream>
 6 #include <string>
 7 #include <algorithm>
 8 #include <list>
 9 #include <map>
10 #include <vector>
11 #include <queue>
12 #include <stack>
13 #include <cmath>
14 #include <cstdlib>
15 // #include <conio.h>
16 using namespace std;
17 #define clc(a,b) memset(a,b,sizeof(a))
18 #define inf 0x3f3f3f3f
19 #define lson l,mid,rt<<1
20 #define rson mid+1,r,rt<<1|1
21 const int N = 11000;
22 const int MOD = 1e9+7;
23 #define LL long long
24 #define mi() (l+r)>>1
25 double const pi = acos(-1);
26 
27 void fre() {
28     freopen("in.txt","r",stdin);
29 }
30 
31 // inline int r() {
32 //     int x=0,f=1;char ch=getchar();
33 //     while(ch>'9'||ch<'0') {if(ch=='-') f=-1;ch=getchar();}
34 //     while(ch>='0'&&ch<='9') { x=x*10+ch-'0';ch=getchar();}return x*f;
35 // }
36 int n,m;
37 int a[N];
38 int sg[N];
39 int mex(int x){
40      int g[110];
41      clc(g,0);
42      for(int i=0;i<n;i++){
43          int res=x-a[i];
44          if(res<0) break;
45          if(sg[res]==-1)
46             sg[res]=mex(res);
47          g[sg[res]]=1;
48      }
49      for(int i=0;i<110;i++){
50          if(!g[i])
51               return i;
52      }
53 }
54 
55 int main(){
56     // fre();
57      while(~scanf("%d",&n),n){
58          // clc(g,0);
59          clc(sg,-1);
60          sg[0]=0;
61          for(int i=0;i<n;i++)
62              scanf("%d",&a[i]);
63          sort(a,a+n);
64          scanf("%d",&m);
65          while(m--){
66              int c;
67              int s=0;
68              scanf("%d",&c);
69              while(c--){
70                  int x;
71                  scanf("%d",&x);
72                  if(sg[x]==-1)
73                      sg[x]=mex(x);
74                  // cout<<sg[x]<<endl;
75                  // system("pasuse");
76                  s^=sg[x];
77              }
78              // cout<<s<<endl;
79              if(s==0)
80                 printf("L");
81              else
82                 printf("W");
83          }
84          printf("\n");
85      }
86      return 0;
87 }

 

转载于:https://www.cnblogs.com/ITUPC/p/5661535.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值