这题是博弈题,题意:给你一些形状的骨牌一样的东西,让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.youkuaiyun.com/jxy859/article/details/6766427
wa了5,6次。一直漏加一个数。。。悲剧啊。。。以后还是理清思路写,不然检查的时候乱乱的。
Run ID | Submit Time | Judge Status | Pro.ID | Exe.Time | Exe.Memory | Code Len. | Language | Author |
4586835 | 2011-09-12 11:22:21 | Accepted | 4023 | 0MS | 264K | 1661 B | G++ | 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();
}
}