博弈论

题目一:

给定nn堆石子,两位玩家轮流操作,每次操作可以从任意一堆石子中拿走任意数量的石子(可以拿完,但不能不拿),最后无法进行操作的人视为失败。

问如果两人都采用最优策略,先手是否必胜。

输入格式

第一行包含整数nn。

第二行包含nn个数字,其中第 ii 个数字表示第 ii 堆石子的数量。

输出格式

如果先手方必胜,则输出“Yes”。

否则,输出“No”。

数据范围

1n1051≤n≤105,
11091≤每堆石子数≤109

输入样例:

2
2 3

输出样例:

Yes


 1 #include <iostream>
 2 using namespace std;
 3 
 4 int main(){
 5     int n;cin>>n;
 6     int res = 0;
 7     while(n--){
 8         int a;cin >> a;
 9         res ^= a;
10     }
11     //异或结果如果为0,先手输, 否则赢
12     if(res) cout << "Yes" << endl;
13     else cout << "No" << endl;
14     return 0;
15 }
View Code

题目二:

现在,有一个nn级台阶的楼梯,每级台阶上都有若干个石子,其中第ii级台阶上有aiai个石子(i1i≥1)。

两位玩家轮流操作,每次操作可以从任意一级台阶上拿若干个石子放到下一级台阶中(不能不拿)。

已经拿到地面上的石子不能再拿,最后无法进行操作的人视为失败。

问如果两人都采用最优策略,先手是否必胜。

输入格式

第一行包含整数nn。

第二行包含nn个整数,其中第ii个整数表示第ii级台阶上的石子数aiai。

输出格式

如果先手方必胜,则输出“Yes”。

否则,输出“No”。

数据范围

1n1051≤n≤105,
1ai1091≤ai≤109

输入样例:

3
2 1 3

输出样例:

Yes


 1 #include <iostream>
 2 using namespace std;
 3 
 4 int main(){
 5     int n;cin >> n;
 6     int res = 0;
 7     //奇数台阶异或结果为0先手输,否则赢
 8     for(int i = 1;i <= n;++i){
 9         int a;cin>> a;
10         if(i % 2) res  ^= a;
11     }
12     if(res)cout << "Yes" << endl;
13     else cout << "No" << endl;
14     return 0;
15 }
View Code
原文地址:https://www.cnblogs.com/sxq-study/p/12287925.html