裸的nim遊戲啦!
#include
#include
int main()
return
0;}
問有幾種方案讓先手必敗
在證明nim遊戲的sg函式的「根據這個判斷被判為n-position的局面一定可以移動到某個p-position」命題時,有這麼一段證明:對於某個局面(a1,a2,…,an),若a1^a2^…^an不為0,一定存在某個合法的移動,將ai改變成ai』後滿足a1^a2^…^ai』^…^an=0。不妨設a1^a2^…^an=k,則一定存在某個ai,它的二進位制表示在k的最高位上是1(否則k的最高位那個1是怎麼得到的)。這時ai^k
#include
#include
int a[2000];
int main()
return
0;}
給出n堆石子,兩個人輪流操作
可以 從任意一堆石子中拿出至少乙個石子
或者 將一堆石子分成三份不為0的石子
先打表求出所有的sg值,然後找一下規律
打表程式是關鍵啊!
#include
#include
#include
#define mem(a,b) memset(a,b,sizeof(a))
const
int maxm=1010;
int sg[maxm],vis[maxm];
inline
void makesg()
}for(int j=0;;j++)
if(!vis[j])
}for(int i=0;i<=100;i++) printf("%d %d %d\n",i,sg[i],i==sg[i]);
}inline
void work()
puts(flag?"first player wins.":"second player wins.");
}int main()
這道題目為上一道題目的簡化版,將變三堆的操作變為變兩堆
#include
#include
#include
int sg[1010],vis[1010];
inline
void makesg()
for(int j=0;;j++)
if(!vis[j])
}for(int i=0;i<=100;i++) printf("%d %d %d\n",i,sg[i],i==sg[i]);
}inline
void work()
puts(flag?"alice":"bob");
}int main()
有n個位置,每個位置可以單向的去往m個位置,給出q個物品的初始位置
兩個人可以移動k步,不能操作的人輸
用dfs拓展可以去的位置求解sg值
區域性定義陣列要記得初始化(為什麼本地執行沒事啊!!!
#include
#include
#include
const
int maxm=222000;
int head[maxm],sg[maxm],cnt,n,q;
int net[1000003],to[1000003];
void addedge(int x,int y)
int dfs(int now)
for(int i=0;;i++) if(!vis[i]) return i;
}void work()
while((scanf("%d",&q))&&q)
puts(flag?"win":"lose");
}}int main()
數論+sg函式
對於每個數字,我們可以將其分解成一系列質數的乘積(也就是分解質因數
這樣,每個數字就可以看出質因數個數的堆
那麼sg[x]=質因數個數
套用最簡易的nim遊戲結論即可
使用線性篩,改進一下分解質數的方法,把求出的sg值給存起來
zoj的評測速度感人
#include
#include
#include
const
int maxm=5000000+1;
int prime[365971],cnt,sg[maxm],a[maxm],n;
bool vis[maxm];
inline
void pre()
}}inline
int getsg(int x)
} if(x>1) k++;
return sg[t]=k;
} inline
void work()
if(!flag) printf("bob\n");
else
} }int main()
return
0;}
給你一段長為n的的線段。
兩個遊戲者輪流在一段長為2,未被染色的線段上塗色。
無法塗色的遊戲者輸
很明顯sg[0]=0,sg[1]=0,sg[2]=1
然後求i的sg,去列舉中間沒染過的線段即可!
#include
#include
#include
const
int maxm=60;
int sg[maxm],vis[maxm];
inline
void makesg()
}}int main()
puts(flag?"yes":"no");
}return
0;}
題意:兩個人輪流選數,選的數x有以下要求:
①,2<=x<=20
②,已選數的倍數不能選
③,不同已選數的倍數的和不能選
當沒有可以選的數的時候,當前選數的人就算輸。
思路,狀壓+sg函式
zoj不刪除檔案讀入顯示 segmentation fault !
#include
#include
#include
#define idx(x) (1<<(x-1))
const
int maxm=1
<<19;
int sg[maxm];
int getsg(int s)
}for(int i=0;;i++)
if(!vis[i]) return sg[s]=i;
}int main()
printf("scenario #%d:\n",case);
if(!getsg(sta)) printf("there is no winning move.\n");
else
printf(".\n");
}printf("\n");
}return
0;}
博弈sg函式
sg函式 個人認為還是用於三種方法都無法解決的情況,如按特殊數字取石子 我們把整個博弈過程抽象為有向無環圖 1.幾項準備工作 mex求最小非負整數mex 0,mex 3,mex 0 sg x mex 就是石頭變少的繼 這樣sg就滿足幾個性質 1.sg x 0時,它的後繼都不為零 2.sg x 0時,...
博弈SG函式
題意 乙個棋盤有n行,每行20格仔,都有一些棋子,兩個人輪流進行這個操作 選擇某一行乙個棋子移動到該行右邊第乙個空的格仔。不能進行的人輸。問先手是否能贏。分析 sg函式的應用,當時自己做的時候沒做出來qaq。終結點是這一行沒有棋子可以走,即0,然後逆推出其他結點的sg函式。每一行的狀態看成是乙個結點...
博弈 SG函式和SG定理
在介紹sg函式和sg定理之前我們先介紹介紹必勝點與必敗點吧.必勝點和必敗點的概念 p點 必敗點,換而言之,就是誰處於此位置,則在雙方操作正確的情況下必敗。n點 必勝點,處於此情況下,雙方操作均正確的情況下必勝。必勝點和必敗點的性質 1 所有終結點是 必敗點 p 我們以此為基本前提進行推理,換句話說,...