(qdulq-2016-c-B)取球博弈(6 point(s))
两个人玩取球的游戏。
一共有N个球,每人轮流取球,每次可取集合{n1
,n2
,n3
}中的任何一个数目。
- 如果无法继续取球,则游戏结束。
- 此时,持有奇数个球的一方获胜。
- 如果两人都是奇数,则为平局。
假设双方都采用最聪明的取法,第一个取球的人一定能赢吗?试编程解决这个问题。
输入格式:
第一行3个正整数n1 n2 n3,空格分开,表示每次可取的数目 (0<n1,n2,n3<100)
第二行5个正整数x1 x2 ... x5,空格分开,表示5局的初始球数(0<xi<1000)
输出格式:
一行5个字符,空格分开。分别表示每局先取球的人能否获胜。能获胜则输出+,次之,如有办法逼平对手,输出0,无论如何都会输,则输出-
输入样例:
1 2 3
1 2 3 4 5
样例输出:
+ 0 + 0 -
输入样例:
1 4 5
10 11 12 13 15
样例输出:
0 - 0 + +
输入样例:
2 3 5
7 8 9 10 11
样例输出:
+ 0 0 0 0
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.7及以上版本的特性。
注意:主类的名字必须是:Main,否则按无效代码处理。
code:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int main(){
int getn[3];
int n[5];
for(int i = 0; i < 3; i++){
scanf("%d",&getn[i]);
}
for(int i = 0; i < 5; i++){
scanf("%d",&n[i]);
}
sort(getn,getn+3);//给能取的球数从小到大排序
for(int i = 0; i < 5; i++){
int x = 0,y = 0;//x代表第一个人总球数,y代表第二个人总球数
while(n[i]){
if(getn[0] > n[i]) break;
bool x1 = false, y1 = false;//两人取完是否是奇数
for(int j = 2; j >= 0; j--){
if(x%2 == 0 && getn[j]%2 == 0 || x%2 != 0 && getn[j]%2 !=0) continue;//如果原来已经有的球数和要取的球数奇偶性相同,总数一定是偶数所以不行
if(getn[j] > n[i]) continue;
x += getn[j];
n[i] -= getn[j];
x1 = true;//如果经过以上条件能取结果总数一定是奇数
break;
}
if(!x1){//如果不能取使得结果为奇数,取最大的
for(int j = 2; j >= 0; j--){
if(getn[j] > n[i]) continue;
x += getn[j];
n[i] -= getn[j];
}
}
//y同理计算
for(int j = 2; j >= 0; j--){
if(y%2 == 0 && getn[j]%2 == 0 || y%2 != 0 && getn[j]%2 !=0) continue;
if(getn[j] > n[i]) continue;
y += getn[j];
n[i] -= getn[j];
y1 = true;
break;
}
if(!y1){
for(int j = 2; j >= 0; j--){
if(getn[j] > n[i]) continue;
y += getn[j];
n[i] -= getn[j];
}
}
}
//判断结果
if(y == 0)
if(x == 0) printf("0 ");
else printf("+ ");
else if(y%2 == 0 && x%2 != 0) printf("+ ");
else if(y%2 != 0 && x%2 == 0) printf("- ");
else if(y%2 == 0 && x%2 == 0) printf("0 ");
else printf("0 ");
}
return 0;
}