(qdulq-2016-c-B)取球博弈(6 point(s))

(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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值