zoukankan      html  css  js  c++  java
  • CF919F A Game With Numbers

    题目:(luogu翻译错的很多)

    Alice和Bob玩游戏,每人有8张牌,牌的值为0~4。每一轮当前玩家选择自己的牌A和对手的牌B,然后将A的值变为( A + B )%5,其中A和B都不是0。

    当一个人手牌全为0时他就赢了。

    T(T<=1e5)组询问,求最后谁赢了,如果都没赢输出Deal。(两个人都是最优方案)

    题解:

    博弈搜索。

    只不过本题有无解情况,因此dfs会卡(应该是我太弱了)。所以考虑用bfs,相当于dfs中直接回溯。

    代码:

    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int num[10][10][10][10],cnt;
    int T;
    int dp[250000],ind[250000];//first:second
    void init()
    {
        for(int a=0;a<=8;a++)
            for(int b=0;a+b<=8;b++)
                for(int c=0;a+b+c<=8;c++)
                    for(int d=0;a+b+c+d<=8;d++)
                        num[a][b][c][d]=++cnt;
    }
    int tn(int a,int b)
    {
        return (a-1)*cnt+b-1;
    }
    int cg(int a[5],int b[5])
    {
        return tn(num[a[1]][a[2]][a[3]][a[4]],num[b[1]][b[2]][b[3]][b[4]]);
    }
    int gt(int a[5])
    {
        int ret = 0;
        for(int i=1;i<=4;i++)ret+=(a[i]!=0);
        return ret;
    }
    struct node
    {
        int a[5],b[5];
        int aa(){return num[a[1]][a[2]][a[3]][a[4]];}
        int bb(){return num[b[1]][b[2]][b[3]][b[4]];}
        int cc(){return tn(aa(),bb());}
        node df()
        {
            node ret;
            for(int i=0;i<=4;i++)ret.a[i]=b[i],ret.b[i]=a[i];
            return ret;
        }
    }tmp;
    queue<node>q;
    int a0[5],b0[5];
    void dfsb(int dep,int sum)
    {
        if(dep==5)
        {
            int c = cg(a0,b0),ga=gt(a0),gb=gt(b0);
            ind[c] = ga*gb;
            if(!(ga*gb))
            {
                if(!ga)dp[c]=1;
                else dp[c]=2;
                tmp.a[0]=8-a0[1]-a0[2]-a0[3]-a0[4],tmp.a[1]=a0[1],tmp.a[2]=a0[2],tmp.a[3]=a0[3],tmp.a[4]=a0[4];
                tmp.b[0]=8-b0[1]-b0[2]-b0[3]-b0[4],tmp.b[1]=b0[1],tmp.b[2]=b0[2],tmp.b[3]=b0[3],tmp.b[4]=b0[4];
                q.push(tmp);
            }
            return ;
        }
        for(b0[dep]=0;b0[dep]+sum<=8;b0[dep]++)
            dfsb(dep+1,sum+b0[dep]);
    }
    void dfsa(int dep,int sum)
    {
        if(dep==5){dfsb(1,0);return ;}
        for(a0[dep]=0;a0[dep]+sum<=8;a0[dep]++)
            dfsa(dep+1,sum+a0[dep]);
    }
    void bfs()
    {
        while(!q.empty())
        {
            tmp = q.front();
            q.pop();
            node v = tmp.df();
            for(int j=1;j<=4;j++)
            {
                if(!v.b[j])continue;
                for(int i=0;i<=4;i++)
                {
                    if(!v.a[i]||(i-j+5)%5==0)continue;
                    v.a[i]--;
                    v.a[(i-j+5)%5]++;
                    int c = v.cc(),c0 = tmp.cc();
                    if(!ind[c])
                    {
                        v.a[i]++;
                        v.a[(i-j+5)%5]--;
                        continue;
                    }
                    if(dp[c0]==2)
                    {
                        dp[c]=1;
                        ind[c]=0;
                        q.push(v);
                        v.a[i]++;
                        v.a[(i-j+5)%5]--;
                        continue;
                    }else if(!dp[c0])
                    {
                        dp[c]=3;
                    }
                    ind[c]--;
                    v.a[i]++;
                    v.a[(i-j+5)%5]--;
                    if(ind[c])continue;
                    if(!dp[c])dp[c]=2;
                    else dp[c]=0;
                    v.a[i]--;
                    v.a[(i-j+5)%5]++;
                    q.push(v);
                    v.a[i]++;
                    v.a[(i-j+5)%5]--;
                }
            }
        }
    }
    int typ;
    int main()
    {
        init();
        dfsa(1,0);
        bfs();
        scanf("%d",&T);
        while(T--)
        {
            memset(a0,0,sizeof(a0));
            memset(b0,0,sizeof(b0));
            scanf("%d",&typ);
            for(int x,i=1;i<=8;i++)
            {
                scanf("%d",&x);
                a0[x]++;
            }
            for(int x,i=1;i<=8;i++)
            {
                scanf("%d",&x);
                b0[x]++;
            }
            int c = typ?cg(b0,a0):cg(a0,b0);
            int ans = dp[c];
            if(!ans)
            {
                printf("Deal
    ");
            }else
            {
                if((ans-1)^typ)
                {
                    printf("Bob
    ");
                }else
                {
                    printf("Alice
    ");
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    SpringBoot结合ShardingSphere实现分库分表、读写分离
    SpringBoot结合ShardingSphere实现主从读写分离
    使用Sentinel实现Spring Cloud Gateway网关流量控制
    使用Sentinel实现热点参数限流
    对比学习UIKit和AppKit--入门级
    UIViewController
    C++的异常处理之一:throw是个一无是处的东西
    About Closure
    理解Objective C 中id
    关于文件压缩的一些小知识
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/9844439.html
Copyright © 2011-2022 走看看