8.23【A】

1927

考虑初始状态下,前半边和后半边的总和差值x

那么B的目标就是让这个差值尽可能接近0

然后A的目标是让这个差值远离0

然后还要知道当前填的这个数,是在前半边还是后半边

对于差值为0的必胜态,往上延申就是只剩一个问号时,能否通过那个问号导向差值为0

还是先从正向DFS考虑,初始时前后差值为a,然后记录问号所在的下标数组

dfs返回的,应该是当前状态下,能否导向差值不为0

然后每层的状态就是?数组和目前差值,以及当前的执行人

对于最底层的叶子节点,对于A,无论如何选都可以导向,直接返回true

对于B,如果差值为正,且最后的问号在前面,那么一定为true

如果差值为正,问号在后面,但差值大于9,也一定为true,否则为false

对于差值为负的情况,则完全对称

然后是遍历与合并

对每个还没确定的问号,遍历从零到9

如果当前是A在执棋,那么只要有一个是true,那就返回true,否则false

如果是B在执棋,只要有一个false,那就返回false,否则true

更自然的底层节点描述

对比

cpp 复制代码
class Solution {
public:
    bool sumGame(string num) {
        int n=num.size(),count=0;
        vector<bool>vis(n,false);//cur为true则为A执棋,否则为B
        function<bool(int,int,bool)>dfs=[&](int delta,int cnt,bool cur)->bool{
            // if(cnt==1){
            //     if(cur){return true;}
            //     for(int i=0;i<n;i++){
            //         if(!vis[i]){
            //             if(i<n/2&&delta>-9){return false;}
            //             if(i>=n/2&&delta<9){return false;}
            //             return true;
            //         }
            //     }
            // }
            if(cnt==0){
                return delta!=0;
            }
            bool res;
            for(int i=0;i<n;i++){
                if(!vis[i]){
                    vis[i]=true;
                    for(int j=0;j<=9;j++){
                        //cnt++;
                        if(i<n/2){res=dfs(delta+j,cnt-1,!cur);}
                        else{res=dfs(delta-j,cnt-1,!cur);}
                        if(res&&cur){break;}
                        if(!res&&!cur){break;}
                    }
                    vis[i]=false;
                    if(res&&cur){break;}
                    if(!res&&!cur){break;}
                }
            }
            return res;
        };
        int tmp=0,i=0;
        for(;i<n/2;i++){
            if(num[i]!='?'){
                vis[i]=true;
                tmp+=(num[i]-'0');
            }else{
                count++;
            }
        }
        for(;i<n;i++){
            if(num[i]!='?'){
                vis[i]=true;
                tmp-=(num[i]-'0');
            }else{
                count++;
            }
        }
        return dfs(tmp,count,true);
    }
};

这版 DFS 的逻辑是正确的,但会超时。

因为 ? 最多可以很多,DFS 枚举量爆炸。

正解

B的获胜条件为什么是"2 * delta == 9 * (rightQ - leftQ)"?即这个等式是怎么来的

如果问号在两侧,B自然可以抵消A的影响,但也可以超过A配的数来进一步抵消差值啊;而且在同侧时,B为什么要选择9-x,一定要配出9呢?

没理解

相关推荐
小郎君6581 小时前
MPTT树复选框的半选状态:一棵百万节点树从递归到计数器,再到区间覆盖
算法
酌沧1 小时前
MemT让记忆成为模型内生能力
jvm·人工智能·算法
Shimeri2 小时前
越卷越像:我用遗传算法做了个"内卷"实验
算法·three.js·数据可视化·遗传算法·进化算法
Evand J2 小时前
【PMSM例程1】永磁同步电机(PMSM)转速与转子电角度观测算法|基于扩展卡尔曼滤波(EKF)的传感器状态估计与误差。附下载链接
算法·电机·1024程序员节·卡尔曼滤波
guo_wen_qiang2 小时前
二叉树的层序遍历-使用双端队列Deque
算法·leetcode·1024程序员节
爱读书的小胖2 小时前
LeetCode 55 跳跃游戏 C 语言解题分析
c语言·数据结构·算法·leetcode·1024程序员节
CCblandy2 小时前
前缀缓存命中率不靠引擎靠排列:本机仿真 3 轮,易变字段放开头 98.0%→0.0%
人工智能·python·算法·自然语言处理·性能优化
上班摸鱼下班游戏2 小时前
Unity 仿生智能算法 从蚁群算法 开始
算法·unity·游戏引擎
pipixia200332 小时前
C++ 面试高频:namespace 的 6 个知识点,从 using 到匿名命名空间
c语言·学习·算法·嵌入式·命名空间·c++面试·匿名命名空间
Navigator_Z4 小时前
LeetCode //C - 1300. Sum of Mutated Array Closest to Target
c语言·算法·leetcode