hdu 4111 Alice and Bob(中档博弈题)★ ★

来源:互联网 发布:js实现旋转 编辑:程序博客网 时间:2024/04/30 17:58

1.每堆部是1的时候,是3的倍数时输否则赢;

2.只有一堆2其他全是1的时候,1的堆数是3的倍数时输否则赢;

3.其他情况下,计算出总和+堆数-1,若为偶数,且1的堆数是偶数,则一定输;

4.不在上述情况下则赢。

#include<stdio.h>int main(){    int js=0;    int _case,i,n,x;    int flag1,flag2,flag,sum;    scanf("%d",&_case);    while(_case--)    {        js++;        flag1=0;        flag2=0;        flag=0;        sum=0;        scanf("%d",&n);        for(i=0;i<n;i++)        {            scanf("%d",&x);            sum+=x;            if(x==1)flag1++;            else if(x==2)flag2++;        }        if(flag1==n)        {            if(flag1%3==0)flag=1;        }        else if(flag1==n-1&&flag2==1)        {            if(flag1%3==0)flag=1;        }        else        {            if((sum+n-1)%2==0&&flag1%2==0)            flag=1;        }        printf("Case #%d: ",js);        if(flag)printf("Bob\n");        else printf("Alice\n");    }    return 0;}


题意:有N堆石头,可以把两堆合成一堆,也可以把一堆去掉一个。

由于总数不变,最终总是要一个个拿完。那么有机会获胜的一方,肯定是先要把所有的合在一起,那么最终就拼奇偶数了。所以双方都要合并。总共就是sigma(ai)+n-1。

而且如果没有某堆只有一个的话,对方是阻挡不住的,没有取完,便被合并了。

所以就要考虑某堆只有一个的情况,单独考虑。

其中的操作包括:

把某堆只有一个的,取走

把两堆只有一个的,合并

把某堆只有一个的,合并给不是一个的

把不是一个的,取走一个

采用记忆化搜索

#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#define N 10005#define LL long long#define inf 1<<29#define eps 1e-7using namespace std;int sg[55][60005];int get_sg(int i,int j){    if(sg[i][j]!=-1)        return sg[i][j];    if(j==1)        return sg[i][j]=get_sg(i+1,0);    sg[i][j]=0;    //某堆只有一个的取掉    if(i>=1&&!get_sg(i-1,j))        sg[i][j]=1;    //把不是1个的取走一个    else if(j>=1&&!get_sg(i,j-1))        sg[i][j]=1;    //把1个的合并给不是1个的    else if(i>=1&&j>0&&!get_sg(i-1,j+1))        sg[i][j]=1;    //把两个1个的合并,其中注意,合并是需要一步的    else if(i>=2&&((j==0&&!get_sg(i-2,j+2))||(j&&!get_sg(i-2,j+3))))        sg[i][j]=1;    return sg[i][j];}int main(){    int n,t,cas=0,k;    scanf("%d",&t);    memset(sg,-1,sizeof(sg));    while(t--)    {        scanf("%d",&n);        int one=0,sum=0;        while(n--)        {            scanf("%d",&k);            if(k==1)                one++;            else                sum+=(k+1);        }        if(sum)            sum--;        printf("Case #%d: ",++cas);        if(get_sg(one,sum))            puts("Alice");        else            puts("Bob");    }    return 0;}



0 0
原创粉丝点击