UESTC794 Balloon Game 博弈

题目链接:Balloon Game

题目大意:

Alice 和 Bob进行一个博弈游戏,他们要摆放气球,保证颜色一样的气球全部相邻出现,现在在一个序列中气球有一部分已经摆放,还有一些未摆放,用"?"表示。比如:a?b?c,那么最后我们能摆放成aabbc,aabdc......

Alice先手摆放气球,他想让气球的颜色种数为奇数个,Bob后手放,想让颜色种数为偶数个,问对于每个询问Alice是否有必胜策略。

题目分析:

第一次看完题目的时候,觉得对于这个博弈问题一些情况是可以解决的:

1.当出现"a?...?a"这种情况下时,中间一段其实已经确定了是"a",所以只有当Alice和Bob不想改变其他现有格局的气球才会放一个,然后他们都会交替的放颜色确定的气球,所以他们的奇偶性能够“反转”最后的结果。

2.当出现"a?...?b"这种情况下时,如果先手不想再增加颜色,完全可以在最后一个b前放个"a",那么这一段的"?"也变成了情况1。

3.当出现"a?...?b"这种情况下时,如果先手想增加颜色的话,那么他会在哪里增加一个新颜色是关键。不管在哪里添加一个新的颜色,我们都会把"?...?",拆成两个序列,这里就需要奇偶讨论了。

1)当"a?...?b"中的"?"个数为偶数个,那么增加一个颜色,会把其拆成一奇一偶两个"???"序列。这种情况其实与单个"a?...?b"中的"?"个数为奇数个一样的。

2)当"a?...?b"中的"?"个数为奇数个,那么增加一个颜色,会把其拆成两偶两个"???"序列。这种情况其实与单个"a?...?b"中的"?"个数为偶数个一样的。

综上所述,能否有必胜的策略的因素有:1)现有颜色个数;2)不确定颜色的气球的奇偶性;3)确定颜色的气球的奇偶性

不过在训练时我没有敢去做的原因是当时以为要考虑到颜色只有26种,那么判断将相当复杂,因为我们要考虑剩下的颜色个数等等。。。不过后来看到hint里有一句:“Though the showing colors in input case will only be a - z, you can use any color.” QAQ~~~

所以看清题目还是最关键啊~

/*author:Samsons
  date:2015.4.12*/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>

using namespace std;

int color[26];
int main()
{
    //freopen("b.in","r",stdin);
    memset(color,0,sizeof(color));
    char tmp='\0';
    int num,num_s,num_n,num_co,ans,i;
    num=0;num_s=0;num_n=0;num_co=0;
    char ch;
    while (scanf("%c",&ch)!=EOF)
    {
        if (ch=='?')
        {
            num++;
            continue;
        }
        if (tmp!=ch) 
        {
            color[ch-'a']=1;
            num_n+=num;
            tmp=ch;
            num=0;
        }
        else 
        {
            color[ch-'a']=1;
            num_s+=num;
            tmp=ch;
            num=0;
        }
    }
    num_n+=num;
    for (i=0;i<26;i++)
        if (color[i]==1) num_co++;
    if (num_n==0)
    {    
        if (num_co % 2==1)
        {
            cout<<"Yes"<<endl;
        }
        else
        {
            cout<<"No"<<endl;
        }
        return 0;
    }
    if (num_n==1)
    {
        cout<<"Yes"<<endl;
        return 0;
    }
    ans=0;
    if (num_n % 2==1) ans=1;
    if (num_s % 2==1) 
        if (ans==1) ans=0;
        else ans=1;
    if (ans==1) cout<<"Yes"<<endl;
    else cout <<"No"<<endl;
    return 0;
}

 

posted on 2015-04-12 20:58  samsons  阅读(375)  评论(0编辑  收藏  举报

导航