ZOJ 3452 Doraemon's Stone Game

Doraemon is playing a game with Dorami. Initially there are piles of stones on the table. Each pile consists of at most 2 stones. Each stone may be black or white. Doraemon and Dorami take turn to take away the stones, the rule is as follows:

  • Doraemon can only take away a white stone each time.
  • Dorami can only take away a black stone each time.
  • If the stone in the bottom is taken away, the whole pile is removed.
  • The first one who can't take away any stone lose. The other one is the winner

Now the piles of stones on the table are known, Doraemon wants to know if he can win. Can you help him?

Input

There are multiple cases (about 45000). 
For each case, the first line is an integer N (1 ≤ N ≤ 6). Then N lines follows. The i-th line contains a string Si and an integer number ai (1 ≤ ai ≤ 1000000000). Si represents a pile of stones. The characters from left to right correspond to stones from top to bottom. The character 'w' means that stone is white and 'b' means that stone is black. The integer ai means there are ai piles of stones represented by Si. It's guaranteed that Si ≠ Sj when i ≠ j.

Output

For each case, output two words separated by a space in one line. The first word should be "win" if Doraemon can win the game if he makes move first, otherwise it should be "lose". The second word should be "win" if Doraemon can win the game if Dorami makes move first, otherwise it should be "lose".

Sample Input
 
2
w 1
b 1
2
b 1
wb 1
Sample Output
 
lose win
lose lose


题意:

A:Doraemon

B:Dorami

A和B一起玩游戏,游戏有如下规则。

1.A每次只能拿走一个白色石头(‘w'表示)

2.B每次只能拿走一个黑色石头(’b'表示)

3.如果最底部的石头被拿走了,那么这一堆石头就不能再拿了

4.谁没有石头拿了,谁就输,另一个就赢

现给你n堆石头,每一种石头堆用字符串si表示(每一种石头堆至多有两个石头),这种石头堆有ai堆。输出A先拿和后拿的结果


思路:

石头堆共有两种情况

1.对于单个的w和单个的b来说各可以让A和B支撑一回合

2.对于wb和bw这种来说,不仅可以让B和A支撑一回合,还可以让对方少一回合

所以对AB来说每次的最优选择是拿第2种的石头堆,但是这样会有个问题:如果属于自己的第2种的石头堆比对手的少怎么办??

那就只能把对手的最优堆破坏成第1种的石头堆。这样计算自己可以拿多少次然后和对手比较即可得出答案。


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
char s[10];
ll a[10];
int n;
int main()
{
    while(~scanf("%d", &n))
    {
        ll bb=0,ww=0,wb=0,bw=0;  //分别记录各种堆的数目
        for(int i=1; i<=n; i++)
        {
            scanf("%s %lld", s, &a[i]);
            int len=strlen(s);
            if(len==2)
            {
                if(s[0]=='b'&&s[1]=='b')
                    bb+=a[i]*2;
                if(s[0]=='w'&&s[1]=='w')
                    ww+=a[i]*2;
                if(s[0]=='w'&&s[1]=='b')
                    wb+=a[i];
                if(s[0]=='b'&&s[1]=='w')
                    bw+=a[i];
            }
            else
                if(len==1)
                {
                    if(s[0]=='w')
                        ww+=a[i];
                    else
                        if(s[0]=='b')
                            bb+=a[i];
                }
        }
        if(bb==ww)         //分别互相抵消,以便计算
            bb=ww=0;
        else
            if(bb<ww)
            {
                ww-=bb;
                bb=0;
            }
            else
            {
                bb-=ww;
                ww=0;
            }
        if(wb==bw)
            wb=bw=0;
        else
            if(wb<bw)
            {
                bw-=wb;
                wb=0;
            }
            else
            {
                wb-=bw;
                bw=0;
            }
        ll ans1=ww+(wb+1+2*bw)/2;     //计算A拿的次数
        ll ans2=bb+(2*wb+bw)/2;         //计算B拿的次数
        if(ans1>ans2)                   //先拿
            printf("win ");
        else
            printf("lose ");
        ans1=ww+bw+wb/2;
        ans2=bb+wb+(bw+1)/2;
        if(ans1>=ans2)                //后拿
            printf("win\n");
        else
            printf("lose\n");
    }
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值