SG函数与例题
Posted smallhester
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SG函数与例题相关的知识,希望对你有一定的参考价值。
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 先手必胜
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 先手必胜
以上是关于SG函数与例题的主要内容,如果未能解决你的问题,请参考以下文章