博弈论SG函数入坑

重点就是找sg函数的值,然后异或 为0 必败否则 必胜。
感谢大佬提供的模板 可用于 打表算SG
dfs 暴力打表

例1
n堆石子,每次不拿超过一半的石子。
找规律可知 n为偶数 SG(n)=(n)/2;奇数 SG(n)= SG(n/2)

#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef long long ll;
const int N=1e3;
ll SG(ll x)
{
    return x%2==0?x/2:SG(x/2);
}
int main()
{
    int t;cin>>t;
    while(t--){
    int n;cin>>n;
    ll a;
    ll ans=0;
    for(int i=0;i>a;
        ll sg=SG(a);
        ans^=sg;
    }
    if(ans==0)
    {
        cout<<"NO"<

例2 杭电 1848
3堆石子,每次取斐波拉切 数。 因为数据都不打就直接打表了

#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef long long ll;
const int N=1e3+5;
int sg[N];int f[N];int s[N];
void SG(int n)
{
    for(int i=1;i<=n;i++)
{
        memset(s,0,sizeof(s));
        for(int j=1;f[j]<=i;j++)
        {
            s[sg[i-f[j]]]=1;
          //  cout<>a>>b>>c)
    {
        int ans=0;
        if(a==0&&b==0&&c==0)
            break;
        ans=(sg[a]^sg[b]^sg[c]);
          if(ans==0)
    {
        cout<<"Nacci"<

例三 hdu1847

每次取 2的幂 打表找规律 发现是1、2、0 的循环
代码改的例二的

#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef long long ll;
const int N=1e3+5;
int sg[N];int f[N];int s[N];
void SG(int n)
{
    for(int i=1;i<=n;i++)
{
        memset(s,0,sizeof(s));
        for(int j=1;f[j]<=i;j++)
        {
            s[sg[i-f[j]]]=1;
          //  cout<>a)
    {

          if(sg[a]!=0)
    {
        cout<<"Kiki"<

例四 hdu1850
题意 输出 先手 第一次 取的方式 多少种

#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef long long ll;
const int N=1e2+5;
int num[N];
int main()
{

    int a,b,c;
while(cin>>a&&a)
{


int ans=0;
for(int i=0;i>num[i];
    ans^=num[i];
    }
    int ta=ans;
    int x=0;
    if(ans>0)
    {

    for(int i=0;i

例 五

#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef long long ll;
const int N=1e3+5;
int num[N];
int main()
{

    int a,b,c;
while(cin>>a&&a)
{


int ans=0;
for(int i=0;i>num[i];
    ans^=num[i];
    }

    if(ans>0)
    {
    cout<<"Rabbit Win!"<

例六
普通多堆取石子

#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef long long ll;
const int N=1e3+5;
int num[N];
int main()
{

    int a,b,c;
while(cin>>a)
{


int ans=0;
for(int i=0;i>b;
    ans^=b;
    }

    if(ans==0)
    {
    cout<<"No"<

例七
大佬的解析



#include 
#include 
#include 
#include 
#include 
#include
using namespace std;
typedef long long ll;
const int N=1e3+5;
int num[N];
int con(int x)
{
    int y=x;
    int c=0;
    int tc=0;
    while(y)
    {
      c+=(y&1);
      y=y>>1;
    }
    return c;
}
int main()
{

    int a,b,c;
    int t;cin>>t;
for(int j=1;j<=t;j++)
{
cin>>a;

int ans=a;
for(int i=0;i>b;
    ans+=con(b);
 //  cout<

例八

你可能感兴趣的:(博弈论SG函数入坑)