SG函数与组合博弈问题

来源:互联网 发布:淘宝v3会员是什么级别 编辑:程序博客网 时间:2024/04/27 13:04

把组合博弈问题抽象成一个有向无环图,有n个棋子在上面移动,当AB两方其中一方移动不了时另一方获胜.
定义mex运算为集合内没有出现过的最小的自然数,则SG(x)=mex{SG(y)(其中y为x所扩展出的状态)}
结论:当有K组的博弈时若SG(n1)^SG(n2)^..SG(nK)!=0时先手获胜,否则后手获胜.
CF上的一道题:

A. The game of Osho
time limit per test2 seconds
memory limit per test64 megabytes
inputpowers.in
outputstandard output
Faheem and Faheema love to play what they call the game of Osho, in this game they choose a number N randomly, the first player subtracts a non-zero number Bk1 less than or equal to N from N, then the second player subtracts number Bk2 (where B is given and ki is a non negative integer number), then again the first and so on until one of the players loses when he/she can’t make any move. In other words, when it’s a player’s turn and N equals 0. For example let’s see this game when B=2 and N=3. The first player Faheem can subtract 1 or 2 the optimal move here is 1, N now equals 2. In her turn Faheema subtract 2 because 1 will make Faheem win, Faheem now can’t play any move and he loses.

After a while they found that this game is boring so they decided to upgrade it, their version combines multiple subgames of the form (Bi, Ni) and the player can choose which of them he wants to play his move in, a player loses when he/she can’t make a move.

Given the subgames, your job is to determine which player wins the whole game assuming that both players play optimally.

Input
The first line contains T, the number of test cases. The next T lines contain G (1 ≤ G ≤ 100) the number of subgames and then follows G pairs of integers (1 ≤ Bi, Ni ≤ 1, 000, 000, 000) describing each subgame.

Output
For each test case print 1 if the first player wins the game, or 2 if the second wins.

Examples
input
3
1 2 3
1 7 3
2 6 11 3 2
output
2
1
2
我是先打表找规律..

#include<stdio.h>#include<iostream>#include<string>#include<string.h>#include<algorithm>using namespace std;#define ll long long#define me(x) memset(x,0,sizeof(x))ll f[105];ll sg[500];ll hashs[500];ll fast(int a,int b){  if (!b) return 1;  if (b&1) return a*fast(a,b-1);  ll t=fast(a,b/2); return t*t;}void  getsg(int b){  int pos;  for (int i=0;i<100;i++)  {    ll t=fast(b,i);    if (t>1000000000) {pos=i-1;break;}    f[i]=t;    pos=i;  }  sg[0]=0;  for (int i=1;i<=105;i++)  {    memset(hashs,0,sizeof(hashs));    for (int j=0;f[j]<=i&&j<pos;j++)    {        hashs[sg[i-f[j]]]=1;    }    for (int j=0;;j++)    {      if (!hashs[j]) {sg[i]=j; break;}    }  }}int main(){  freopen("powers.in","r",stdin);  int T;  scanf("%d",&T);  while (T--){    //memset(sg,0,sizeof(sg));    int n;    scanf("%d",&n);    int sum=0;    for (int i=1;i<=n;i++)    {      int b,N;      scanf("%d%d",&b,&N);      //getsg(b);      if (b&1) {if (N&1)sum=sum^1;else sum=sum^0;}      else {        if (N%(b+1)==b)sum=sum^2;        else if (N%(b+1)&1) sum=sum^1;             else sum=sum^0;        }    }    if (!sum) printf("2\n");    else printf("1\n");  }}
0 0
原创粉丝点击