真是令人惊讶,三大经典博弈都可以通过数学运算得到结论简单解决!
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 }
完。