hdu 4023

这题是博弈题,题意:给你一些形状的骨牌一样的东西,让a和b分别用竖着的1*2骨牌和横着的1*2的骨牌去覆盖,不能够重叠,谁先不能放谁输。一开始想把每一类的sg值求出然后异或就好了,但是这个sg状态太难找了,只能用一般的模拟来模拟最佳策略。分析如下

根据每个方块的能被放的情况对方块分类,共5类

1-- 2A  2--2B                                              ///1

3 4-- 1A OR 2B       5 6 --1B OR 2A        ///2

7 8 1A1B OR 1A    9 10--1A1B OR 1B  ///3

11 12 13 14 1A OR 1B                            ///4

15 2A OR 2B                                             ///5

总游戏 其实就是5类游戏的组合游戏,但是SG函数很难找状态,还是找规律约去不影响结果的平衡局势即可。

根据贪心策略 有 5>2>4>3>1

参考 http://blog.csdn.net/jxy859/article/details/6766427 

wa了5,6次。一直漏加一个数。。。悲剧啊。。。以后还是理清思路写,不然检查的时候乱乱的。

Run IDSubmit TimeJudge StatusPro.IDExe.TimeExe.MemoryCode Len.LanguageAuthor
45868352011-09-12 11:22:21Accepted40230MS264K1661 BG++xym2010
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<iostream>
using namespace std;
int d[16],vd[16];
void work()
{
    int pos=0,a=0,b=0;
    if(d[15]%2!=0)
    {
        a+=2;
        pos^=1;
    }
    if(d[5]+d[6]>d[3]+d[4])
    {
        int tem=d[5]+d[6]-d[3]-d[4];
        if(pos==0)
        {
            a+=2*(tem/2+tem%2);
			b+=tem/2;
            pos^=tem%2;
        }
        else
        {
            a+=2*(tem/2);
			b+=(tem/2+tem%2);
            pos^=tem%2;
        }
    }
    else if(d[5]+d[6]<d[3]+d[4])
    {
        int tem=d[3]+d[4]-d[5]-d[6];
        if(pos==0)
        {
            b+=2*(tem/2);
			a+=tem/2+tem%2;
            pos^=tem%2;
        }
        else
        {
            b+=2*(tem/2+tem%2);
			a+=(tem/2);
            pos^=tem%2;
        }
    }  
	if((d[11]+d[12]+d[13]+d[14])%2==1)
    {
		if(pos==0)a+=1;
		else
			b+=1;
        pos^=1;
    }
    if(d[7]+d[8]>d[9]+d[10])
    {
        int tem=d[7]+d[8]-d[9]-d[10];
		   a+=tem;
        if(pos==0)
           b+=tem/2;
        else
           b+=tem/2+tem%2;
        pos^=tem%2;
    }
    else
    {
        int tem=d[9]+d[10]-d[8]-d[7];
		b+=tem;
        if(pos==1)
          a+=tem/2;
        else
            a+=tem/2+tem%2;
        pos^=tem%2;
    }   
    a+=d[1]*2;
    b+=d[2]*2;
    if(a>b)printf("Alice\n");
    else printf("Bob\n");
}
int main()
{
    int T,t;
    scanf("%d",&T);
    for(t=1;t<=T;t++)
    {
        for(int i=1;i<=15;i++)
            scanf("%d",&d[i]);
        printf("Case #%d: ",t);
        work();
    }
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值