码迷,mamicode.com
首页 > 其他好文 > 详细

SG函数与例题

时间:2019-08-18 13:40:51      阅读:90      评论:0      收藏:0      [点我收藏+]

标签:out   初始化   集合   gif   namespace   std   移动   cst   alt   

int sg[maxn];//sg[n] n表示每堆数量
int s[k];//每次能取的值,下标从0开始,0 ~ k-1,必须有序,可以sort(s,s+k);
bool vis[maxn];
const int k;//k是集合s的大小 

void get_sg()
{
    int i,j;
    for(i=0;i<maxn;i++)
    {
        memset(vis,0,sizeof(vis));
        j=0;
        while(j<k&&s[j]<=i)
        {
          vis[sg[i-s[j]]]=1;
        j++;
        }
        for(j=0;j<maxn;j++)
        if(!vis[j])
        {
            sg[i]=j;
            break;
        }
    }
}

int main()
{
    ...    //将s数组初始化
    memset(sg,-1,sizeof(sg));
    get_sg();
    if(sg[n]==0) //先手必败
    else    //先手必胜

   //如果有多堆,则
   // num=sg[n1]^sg[n2]^sg[n3]^....^sg[nx];
   // if(num==0) 则先手必败
   // else    先手必胜
    ...
}

 

Good Luck in CET-4 Everybody!

 HDU - 1847 

题意:n 张牌( 1 <= n <= 1000),两个人轮流取牌,只能取2的幂次张牌 (即:1,2,4,8,16...),最后抓完牌的人获胜

题解:一堆,s数组取值为 2 ^ i (0 <= i <= 11)

技术图片
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<stack>
#include<cstdlib>
#include<queue>
#include<set>
#include<string.h>
#include<vector>
#include<deque>
#include<map>
using namespace std;
#define INF 0x3f3f3f3f
#define eps 1e-4
#define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
typedef long long LL;
typedef long long ll;
const int maxn = 1e3 + 5;
const int mod = 998244353;

#define k 12
int sg[maxn];//sg[n] n表示每堆数量
int s[k];//每次能取的值,下标从0开始,0 ~ k-1,必须有序,可以sort(s,s+k);
bool vis[maxn];


void get_sg() {
    int i, j;
    for (i = 0; i < maxn; i++) {
        memset(vis, 0, sizeof(vis));
        j = 0;
        while (j < k && s[j] <= i) {
            vis[sg[i - s[j]]] = 1;
            j++;
        }
        for (j = 0; j < maxn; j++)
            if (!vis[j]) {
                sg[i] = j;
                break;
            }
    }
}

int main()
{
    int n;
    for(int i = 0; i < k; i++)
        s[i] = int(pow(2,i));
    while(cin >> n) {
        memset(sg, -1, sizeof(sg));
        get_sg();
        if (sg[n] == 0) //先手必败
            puts("Cici");
        else
            puts("Kiki");//先手必胜
    }

    //如果有多堆,则
    // num=sg[n1]^sg[n2]^sg[n3]^....^sg[nx];
    // if(num==0) 则先手必败
    // else    先手必胜

}
View Code

 

 Northcott Game

 HDU - 1730 

题意:如图所示,游戏在一个n行m列(1 ≤ n ≤ 1000且2 ≤ m ≤ 100)的棋盘上进行,每行有一个黑子(黑方)和一个白子(白方)。执黑的一方先行,每次玩家可以移动己方的任何一枚棋子到同一行的任何一个空格上,当然这过程中不许越过该行的敌方棋子。双方轮流移动,直到某一方无法行动为止,移动最后一步的玩家获胜。

题解:每一行中加的距离可以看作是石子的堆数,因为每一个当一个人往两侧走的时候,另一个人可以往那个方向走直至距离一样,这个基础上它还可以再走,所以中间的距离只会减少不会增加,就可以看作是一个多堆石子的NIM游戏

技术图片
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<stack>
#include<cstdlib>
#include<queue>
#include<set>
#include<string.h>
#include<vector>
#include<deque>
#include<map>
using namespace std;
#define INF 0x3f3f3f3f
#define eps 1e-4
#define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
typedef long long LL;
typedef long long ll;
const int maxn = 1e3 + 5;
const int mod = 998244353;

#define k 12
int sg[maxn];//sg[n] n表示每堆数量
int s[k];//每次能取的值,下标从0开始,0 ~ k-1,必须有序,可以sort(s,s+k);
bool vis[maxn];


void get_sg() {
    int i, j;
    for (i = 0; i < maxn; i++) {
        memset(vis, 0, sizeof(vis));
        j = 0;
        while (j < k && s[j] <= i) {
            vis[sg[i - s[j]]] = 1;
            j++;
        }
        for (j = 0; j < maxn; j++)
            if (!vis[j]) {
                sg[i] = j;
                break;
            }
    }
}

int main()
{
    int n,m;
    while(cin >> n >> m) {
        int a,b;
        int flag = 0;
        while(n--){
            cin >> a >> b;
            flag ^= (abs(a - b) - 1);
        }
        if(flag == 0) puts("BAD LUCK!");
        else puts("I WIN!");
    }

    //如果有多堆,则
    // num=sg[n1]^sg[n2]^sg[n3]^....^sg[nx];
    // if(num==0) 则先手必败
    // else    先手必胜

}
View Code

 

SG函数与例题

标签:out   初始化   集合   gif   namespace   std   移动   cst   alt   

原文地址:https://www.cnblogs.com/smallhester/p/11371983.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!