Game

Game

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)
Total Submission(s): 710    Accepted Submission(s): 236


Problem Description

 

Alice and Bob are playing game with each other. They play the game on a 2D board. Alice has many vertical 1*2 tiles while Bob has many horizontal 2*1 tiles. They take turn to place their own tiles on the board. Considering about that the tiles cannot overlap each other, the player cannot do the placement any more loses. Since this is such a complex game that they could not find optimal method to play that, Alice decide to simplify this game by replace the large 2D board by some small ones. Alice set up a lot of Tetris tiles instead of the original 2D board. In the other words, the player can only place their own vertical or horizontal tiles on the Tetris-like board. Each player can choose one possible place on any Tetris tiles to place its own tiles. In fact, there are following 15 types of Tetris playground.

The playground cannot be transformed in any ways, including reflection and rotation.
Given the number of each type of tiles, you are asked to determine who will win the game if Alice plays first and both players are playing optimal.
Input

 

There are multiple test cases; the first line of input contains a single integer denoting the number of test cases.
For each test case, there are only one line contains 15 integers denoting the number of Tetris tiles of the above 15 types. All the numbers are no greater than 100.
Output

 

For each test cases, output “Alice” if Alice will win the game and both player plays optimally, “Bob” otherwise.
Sample Input

 

3
5 4 0 0 0 0 0 0 0 0 0 0 0 0 0
5 5 0 0 0 0 0 0 0 0 0 0 0 0 0
100 100 0 0 0 0 0 0 0 0 0 2 1 0 0
Sample Output

 

Case #1: Alice
Case #2: Bob
Case #3: Alice

 

分析:

大致题意:两个人在15中地板上,分别放1*2和2*1的瓷砖,谁不能再放,谁就输

思路分析:http://www.cnblogs.com/kuangbin/archive/2012/08/23/2652902.html

1、(15)为一组,由于(15)一旦放一个瓷砖,那么不仅使自己走出了一步,还能为自己留一个稳定走位,同时又能使对手失去两个位置,所以在(15)放一个瓷砖是效益最高的走法,因而双方最先都会争(15)

2、(1)(2)是一组,分别是Alice和Bob的稳定走位,所以可以放到最后去考虑

3、(3)(4)(5)(6)是一组,至于为什么这四个是一组,我们不妨从Alice的角度分析下一。如果Alice走(5)或(6),那么Alice同时可以获得一稳定走位,并让Bob失去一个位置,如果Alice走(3)(4),那么Alice可以让Bob失去两个位置,所以这两种走法对Alice的收益是相同的。反过来,对Bob而言也是一样的。既然两种走法相同,那么便于我们的统计,不妨先让Alice走(5)(6),Bob走(3)(4),直到一方走完自己的主场,然后再去瓜分剩下的(3)(4)或者(5)(6)

4、(7)(8)(9)(10)是一组,(11)(12)(13)(14)是一组,为什么这样分呢?

首先,从Alice的角度来讲,如果走(7)(8),都可以使Bob失去一个位置,走(11)(12)(13)(14)也是如此,但两种走法对Alice的收益来讲是不同的,如果Alice走(11)~(14)其中的任意一个,而Bob无论走(7)或(8)都会留一个稳定走位给Alice,而如果Alice走(7)(8)而Bob走(11)~(14)就没有这种效果了。因而Alice一定会先走(11)~(14),再走(7)(8)。同样的道理,Bob一定会先走(11)~(14),再走(9)(10)

至于(7)(8)(9)(10)的瓜分,从Alice角度来讲,走(7)(8)不仅会使自己走出了这一步,同时会使Bob失去一个位置,而Alice走(9)(10)却只能使自己走出一步罢了,并不能给Bob带来什么损失,所以Alice一定优先走(7)(8),而对于Bob来讲,他一定会先走(9)(10),最后如果(7)(8)或者(9)(10)有剩余,双方再继续瓜分

所以Alice和Bob的选择顺序如下:

Alice:(15)->[(5),(6)]->[(3),(4)]->[(11),(12),(13),(14)]->[(7),(8)]->[(9),(10)]->(1);

Bob:(15)->[(3),(4)]->[(5),(6)]->[(11),(12),(13),(14)]->[(9),(10)]->[(7),(8)]->(2).

而现在只需模拟一遍他们的选择,得到他们选择的先后now,并记下还有多少个稳定走位,就行了

# include<stdio.h>
int main()
{
    int nCase,cnt=1,i;
    int s1,s2,temp1,temp2,res;
    int now;//记录选择次序的先后
    int sign[16];
    scanf("%d",&nCase);
    while(nCase--)
    {
        s1=0;
        s2=0;
        now=1;
        for(i=1;i<=15;i++)
            scanf("%d",&sign[i]);
        if(sign[15]%2==1)//(15)为奇数,Alice就得到个稳定走位,次序转换
        {
            s1+=1;
            now=2;
        }
        temp1=sign[5]+sign[6];
        temp2=sign[3]+sign[4];
        if(temp2>temp1)
        {
            res=temp2-temp1;
            if(res%2==0)
            {
                s2+=res/2;
            }
            else
            {
                if(now==1)
                {
                    now=2;
                    s2+=res/2;
                }
                else
                {
                    now=1;
                    s2+=res/2+1;
                }
            }
        }
        else if(temp2<temp1)
        {
            res=temp1-temp2;
            if(res%2==0)
            {
                s1+=res/2;
            }
            else
            {
                if(now==2)
                {
                    now=1;
                    s1+=res/2;
                }
                else
                {
                    now=2;
                    s1+=res/2+1;
                }
            }
        }
        if((sign[11]+sign[12]+sign[13]+sign[14])%2==1)//这里只会改变顺序,不会产生稳定走位
        {
            if(now==1)
                now=2;
            else now=1;
        }
        temp1=sign[7]+sign[8];
        temp2=sign[9]+sign[10];
        if(temp2>temp1)//这里和前面(3)(4)(5)(6)的情况差不多,但还是有所区别;认真走一遍,应该没问题
        {
            res=temp2-temp1;
            if(res%2==0)
            {
                s2+=res/2;
            }
            else
            {
                if(now==1)
                {
                    now=2;
                    s2+=res/2+1;
                }
                else
                {
                    now=1;
                    s2+=res/2;
                }
            }
        }
        else if(temp2<temp1)
        {
            res=temp1-temp2;
            if(res%2==0)
            {
                s1+=res/2;
            }
            else
            {
                if(now==2)
                {
                    now=1;
                    s1+=res/2+1;
                }
                else
                {
                    now=2;
                    s1+=res/2;
                }
            }
        }
        s1+=sign[1]*2;
        s2+=sign[2]*2;
        printf("Case #%d: ",cnt++);
        if(now==1)
        {
            if(s2>=s1)
                printf("Bob\n");
            else
                printf("Alice\n");
        }
        else
        {
            if(s1>=s2)
                printf("Alice\n");
            else printf("Bob\n");
        }
    }
    return 0;
}

 

posted on 2012-11-09 21:02  即为将军  阅读(352)  评论(0)    收藏  举报

导航