summer

summer

Description

This summer is so hot that YSY is overcame by the heat and at this time nothing could be better than cool water. 
Showering with the cool water makes YSY so happy. But he feels lonely and invites his friend to enjoy it. 
That's a really good game with the following rules:

First: We have two big buckets which is so big that you cannot fill up it.The one of them is filled with N gallon water 
while the other is empty.
Second: We also have four small cups, which can take 1, 3, 7 and 8 gallon water separately.
Third: YSY and his friend take turns to carry some water from the bucket which is filled with water 
to the empty one with one of those cups, but YSY always starts first. 
The one who makes the filled bucket empty wins and the loser have to give a shower to the winner,
that is really cool, isn't it?There're some interesting rules would be added into this game:
If YSY's friend is a boy, absolutely, YSY will try his best to win, his friend as well.
If YSY's friend is a girl, YSY will try his best to lose. However, the girl will try her best to win.

Could you please tell us YSY can win this game or not?
 
 
Input

Several test cases;
Every case contains two lines.
The first line tells an integer N(1<=N<=10000),which means how much water it contains;
The second line is a string meaning YSY’s friend's name, which is made up with blanks and alphabets and its length is not longer than 100, we consider YSY's friend is a girl if the first letter of the name is uppercase, or a boy.

 
Output

If YSY wins, just print "Yes!", else print "Nooo!!!";

 Sample Input

8
Conda
8
noka

Sample Output

Nooo!!!
Yes!

分析:

这道题是巴什博弈的一种变形,减法博弈
  用S表示一个正整数构成的集合,基于S所定义的减法游戏可以描述如下:
  有一个由n个石子组成的石子堆,两名玩家轮流从中拿走石子,每次拿走石子的个数只能是集合S中的数。拿走最后一枚石子的玩家获胜。
该题大意:①YSY和另一个人轮流在{1,3,7,8}中选其中一个单位的杯子,将一桶的水转移到另一桶去,谁最后将水取玩,谁就获胜;YSY先取
               ②如果对方是男生,YSY和对方都尽量赢;如果对方是女生,SYS尽量输,对方尽量赢
               ③名字第一个字母是大写的就是女生,否则为男生
思路:这道题咋一看较难,但仔细分析就有些思路了。
               ①先不考虑男女生问题,就减法博弈而言,应先将可能出现的必胜点找出来,标为1;
               ②用sign[]记录必胜点和必败点,如果对方是男生,就直接看sign[n]的值就能判断了;
               ③如果对方是女生,sign[n]=0,那就必败;如果sign[n]=1,就继续讨论:
                  直接想有些困难,那就罗列几个尽量败的情况观察:
 1  2  3  4  6  7  8  10  11 12  13   14
 sign[n]  1  0  1  0  0  0  0  0
                 由上表可得,n为偶数时,YSY都能达到必败点;当n大等于9时,YSY也都能进入必败点,以下给出证明。
证明:①如果n为偶数,令n=2*k,k为正整数,2*k=1+1+2*(k-1)···这样就可看出,YSY想尽量输的话,最后就取决于YSY所面对的sign[2]的值,而sign[2]=0,则必败
        ②当n>=9时,令n=2*k+7,k为正整数,2*k=8+2*k-1=8*c+2*t-1,
          如果c为奇数,那就可以以此轮流取8,将2*t-1控制到8以内,此时对方处在sign[2*t-1];
          如果c为偶数,那就可以将其中一个8拆成1+7,这样数目就变成了c+1个,同样为奇数,轮流取,将2*t-1控制到8以内,此时对方同样处在sign[2*t-1];
          这时t∈(1,4),sign[2*t-1]=1,那么对方必胜
那代码就可以写出了,如下:
# include<stdio.h>
# include<string.h>
int s[4]={1,3,7,8};
int sign[10010];
char name[110];
void solve()
{
    memset(sign,0,sizeof(sign));
    sign[1]=1;
    int i,j;
    for(i=2;i<=10005;i++)
    {
        for(j=0;j<4;j++)
        {
            if(i-s[j]>=0)
            {
                if(sign[i-s[j]]==0)
                {
                    sign[i]=1;
                    break;
                }
            }
        }
    }
}
int main()
{
    int n;
    solve();
    while(scanf("%d",&n)!=EOF)
    {
        getchar();//见http://www.cnblogs.com/jiangjun/archive/2012/05/16/2503676.html用法2
        gets(name);
        if(name[0]>='A'&&name[0]<='Z')//女生的情况
        {
            if(sign[n]==0)
                printf("Nooo!!!\n");
            else
            {
                if(n>=9||n%2==0)
                {
                    printf("Nooo!!!\n");
                }
                else
                {
                    printf("Yes!\n");
                }
            }
        }
        else//男生的情况
        {
            if(sign[n]==1)
                printf("Yes!\n");
            else
                printf("Nooo!!!\n");
        }
    }
    return 0;
}

 

 

 

 

                     

posted on 2012-10-28 09:17  即为将军  阅读(233)  评论(0)    收藏  举报

导航