51nod三大经典博弈(模板)

真是令人惊讶,三大经典博弈都可以通过数学运算得到结论简单解决!

Bash游戏(数学余数方法)

关键:必输局面,谁面对(k+1)个石子这个局面必输!

 1 #include <iostream>
 2 using namespace std;
 3 
 4 int main()
 5 {
 6     int T;
 7     cin>>T;
 8     while(T--)
 9     {
10         int n,k;
11         cin>>n>>k;
12 
13         if(n%(k+1)) cout<<'A'<<endl;
14         else cout<<'B'<<endl;
15     }
16 
17     return 0;
18 }

这个游戏刚开始我是找不到规律的,是通过k==2时推算出来的(数小游戏简单而且比较好找规律嘛,发现只要是3的倍数(谁面对3的倍数局面)先手必输)。

这里只不过把k=2扩展到了n维,套路还是一样。

 1 #include <iostream>
 2 using namespace std;
 3 
 4 int main()
 5 {
 6     int T;
 7     cin>>T;
 8     while(T--)
 9     {
10         int n;
11         cin>>n;
12 
13         if(n%3) cout<<'A'<<endl;
14         else cout<<'B'<<endl;
15     }
16 
17     return 0;
18 }

Nim游戏(数学异或方法)

关键:必输局面,谁面对2堆石子相同这个局面必输!

 1 #include <iostream>
 2 using namespace std;
 3 
 4 int main()
 5 {
 6     int n;
 7     cin>>n;
 8     int ans=0;//0异或任何数都是那个数
 9     for(int i=1;i<=n;i++)
10     {
11         int x;
12         cin>>x;
13 
14         ans=ans^x;
15     }
16 
17     if(ans) cout<<'A'<<endl;
18     else cout<<'B'<<endl;
19 
20     return 0;
21 }

威佐夫游戏(数学黄金比例,黄金分割方法)

关键:必输局面,谁面对黄金比例分割石子这个局面必输!(如a==(1+sqrt(5))/2*(b-a),两个数构成了黄金分割等式)

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cmath>
 4 using namespace std;
 5 const double best=(1+sqrt(5.0))/2.0;//黄金比例分割是(1+sqrt(5.0))/2.0
 6 
 7 int main()
 8 {
 9     int T;
10     cin>>T;
11     while(T--)
12     {
13         int a,b;
14         cin>>a>>b;
15 
16         if(a>b) swap(a,b);//从小到大交换顺序方便
17         //int k=b-a;
18         if(a==int((b-a)*best)) cout<<'B'<<endl;
19         else cout<<'A'<<endl;
20     }
21 
22     return 0;
23 }

完。

原文地址:https://www.cnblogs.com/redblackk/p/9968908.html