10.5二分专练,二分边界情况,+1不加1的判断,方向判断,各种DEBUG

5

https://leetcode.cn/problems/minimum-speed-to-arrive-on-time/submissions/570242512/
就是说总时间是
前n-1量汽车的运行时间,向上取整,然后再加上最后一辆列车的运行时间
最快的话是需要n-1个小时
搜索空间就是时速,左边界是1,右边界是其中最大值
当为最大值时,就是n-1再加上最后的距离与该时速的比值
如果大于目标时间hour,说明不满足条件,应当增大速度,即向右侧找,同时舍去该解,left=mid+1
如果小于等于hour,说明满足条件,可以去找左侧的最小值,right=mid
不应该加1
在这里插入图片描述

class Solution {
public:int minSpeedOnTime(vector<int>& dist, double hour) {int leftB=1;int rightB=10e7;// for(int i:dist){//     if(i>rightB){//         rightB=i;//     }// }if(dist.size()>=hour+1){return -1;}int mid=0;while(leftB<rightB){int tarN=0;mid=(leftB+rightB)/2;for(int i=0;i<dist.size()-1;i++){tarN+=((dist[i]/mid)+((dist[i]%mid)?1:0));}double tar=double(dist[dist.size()-1])/double(mid);// cout<<"预期的小时部分"<<tar<<endl;tar+=tarN;if(tar>hour){// cout<<"此时左边界为"<<leftB<<"右边界为"<<rightB<<"速度为"<<mid<<"总用时是"<<tar<<"前n-1量用时为"<<tarN<<endl;leftB=mid+1;}else{//cout<<"此时左边界为"<<leftB<<"右边界为"<<rightB<<"速度为"<<mid<<"总用时是"<<tar<<"前n-1量用时为"<<tarN<<endl;rightB=mid;}}mid=(leftB+rightB)/2;return mid;}
};

优化

对初始的上界与下界进行优化,下界至少是1的,但是更好情况是路程总和与要求时间的平均,或者说这个就是最好的期望解,即每段都是相同的,
对于上界,没看懂它的优化,先放在这里

l = max(1, int(sum(dist)//hour))
r = int(sum(dist)//(hour-n+1) + 1)

但是要注意,下界在用平均的时候,务必要增加一个与1的Max判断,就是为了防止0出现在搜索空间当中
而且在算累和的时候,务必要注意数据范围,一般应当要用Longlong来记录累和,用Int的话必爆

在用上平均值优化后,优化效果并不是很好\\,甚至还有点拉托了

Debug

限制值错误

第一次是因为忽略了非整数部分的取值,即没有向上取整,即
tarN+=(dist[i]/mid);
改为
tarN+=((dist[i]/mid)+((dist[i]%mid)?1:0));
即可

上界取值错误

在这里插入图片描述
这是因为一开始认为速度右侧最大值是里程里的最大值,但是如果它是在最后的话,完全可以使速度达到一个很大的值,从而使最后一段的速度降下来
这个问题,个人目前没有很好的解决办法
参考官方题解
由于时限最小单位是0.01,最大的距离是 1 0 5 10^5 105,所以在最后一段,极限的最快速度就是 1 0 7 10^7 107,如果再快的话,就会导致时间小于0.01了,所以时间上限就是 1 0 7 10^7 107

小数除法

这次错是因为最后一段的小数部分,由于是让整数之间进行相除,即
double tar=(dist[dist.size()-1])/(mid);
会导致tar虽然是double类型,但根本不会产生小数,只有把分子分母都强转为double,才可以使tar为小数,即
double tar=double(dist[dist.size()-1])/double(mid);

4

https://leetcode.cn/problems/minimized-maximum-of-products-distributed-to-any-store/
就是去搜索每个店被分到的商品最大值x,
左边界是1,右边界是其中的最大值
x越大,那么分出的商店数越少;
限制条件是商店数,如果x对应到的商店数k,
大于给定的商店数n,则说明不满足条件,应当向减少商店数的方向去搜索,即x大、右侧去搜索,left=mid+1
小于等于给定的商店数,说明满足条件,尝试增大商店数,即向左侧去搜索,right=mid,并保留该解
只剩两个值的时候,应首先向左侧去搜索,所以不加1

在这里插入图片描述

一遍过

class Solution {
public:int minimizedMaximum(int n, vector<int>& quantities) {int leftB=1;int rightB=quantities[0];for(int i:quantities){if(i>rightB){rightB=i;}}if(n<=quantities.size()){return rightB;}int mid;while(leftB<rightB){int tar=0;mid=(leftB+rightB)/2;for(int i:quantities){tar+=((i/mid)+((i%mid)?1:0));}if(tar>n){leftB=mid+1;}else{rightB=mid;}}mid=(leftB+rightB)/2;return mid;}
};

3

https://leetcode.cn/problems/minimum-limit-of-balls-in-a-bag/description/

歧途——贪心大顶堆

一开始想法就是维护一个最大堆,每次都取堆顶元素,然后给他除以2,如此循环操作给定的次数,最后堆顶就是代价
之所以要除以2,是因为如果不这样的话,必然会有比2还大的数在里面,相当于没整

考虑到不能整除的问题,每次加入就是加入(num)/2与(num+1)/2,这样就是如果能整除,加的也是两个相同的数;不能整除,就是一个左值,一个右值

class Solution {
public:int minimumSize(vector<int>& nums, int maxOperations) {priority_queue<int>p;for(int i=0;i<nums.size();i++){p.push(nums[i]);}for(int i=1;i<=maxOperations;i++){int num=p.top();p.pop();p.push(num/2);p.push((num+1)/2);}return p.top();}
};

问题
在这里插入图片描述
考虑这种情况,9-》4和5,5再拆分成2和3,导致结果是4,但如果一开始分成3和6,第二次拆成3,3,3,就会使最后结果为3,贪心确实行不通

贪心行不通的原因

在这里插入图片描述
参照题解,贪心的思路无非是在处于2y与3y之间的值,使其变为y与2y之间的值,那么要让原值完全处于y之下,则需要3次操作,而如果是变为<=y与y与2Y之间的两个数,则只需要2次操作

也就是逆向思维不去向怎么从原始值变出最优解,而是先假定一个最优解,然后看各个值怎么达到这个最优解
而问题也就出现在上面的贪心思路到这个最优解的路径上了

二分

如果卡死一个最优解的线,每个袋子要达到这个最优解,必然要有一个策略
就是对于含有x个东西的袋子,怎么拆分才能使其产生的袋子都达到y以下
显然也应当逆向思维,每次拆分相当于多了一个袋子,最后不就是把x个东西分到k个袋子当中,每个袋子里装的数量不超过y吗?
这样的话最优解必然也是每个袋子里装的都是y
而按照其它划分方法,尤其是上面的贪心,每次分一半的话,很有可能多用
就是把问题看成,一共有x个东西,每个袋子只能装y个,问一共需要多少个袋子的问题

那么每个袋子能装的最大值是数组里的最大值,最小值是1,
限制条件就是切分的次数,即多用的袋子的数量o
如果袋子容量对应的切分数大于o的话,说明不满足条件,应当要减少切分次数,即扩大每个袋子的容量以减少袋子所用的数量
如果小于等于o,说明满足条件,保留该解,并尝试缩小袋子容量,即向左侧找,right=mid,从而减小开销
对于Mid,由于满足条件时,是尝试向左取值,所以不应当+1;

搜索空间就是袋子所能放的数量

在这里插入图片描述

class Solution {
public:int minimumSize(vector<int>& nums, int maxOperations) {int leftB=1;int rightB=nums[0];for(int i:nums){if(i>rightB){rightB=i;}}int mid=1;while(leftB<rightB){int sum=0;mid=(leftB+rightB)/2;for(int i:nums){sum+=(i/mid)+((i%mid)?0:-1);}if(sum>maxOperations){cout<<"此时左边界为"<<leftB<<"右边界为"<<rightB<<"袋子装的数量为"<<mid<<"切分数是"<<sum<<endl;leftB=mid+1;}else{cout<<"此时左边界为"<<leftB<<"右边界为"<<rightB<<"袋子装的数量为"<<mid<<"切分数是"<<sum<<endl;rightB=mid;}}mid=(leftB+rightB)/2;return mid;}
};

DEBUG

端点情况

考虑这个切分,就是想象成一个线段,切分成k段不大于Y的子段的次数
如果刚好达到端点的情况,就不应当再继续分
即将 sum+=(i/mid)改为sum+=(i/mid)+((i%mid)?0:-1);

2

https://leetcode.cn/problems/koko-eating-bananas/
最大值肯定是香蕉堆里的最大值
最小值期望是香蕉总数除以小时数
如果堆数大于小时数,则必然无解
速度越快,那么小时数越小,但不是规则变动的
满足条件是要让小时数和给定的去比较
也是从左到右是递减的
如果小时数大于给定的话,就是不满足条件,应当向右侧去找
如果小于的话,是满足条件,应当向左侧去找代价更小的

在这里插入图片描述

class Solution {
public:int minEatingSpeed(vector<int>& piles, int h) {int rightB=piles[0];long long sum=0;for(int i:piles){sum+=i;if(i>=rightB){rightB=i;}}int leftB=sum/h;//int leftB=((sum/h)?sum/h:1);if(piles.size()>=h){return rightB;}if(leftB==0){return 1;}int mid=0;// cout<<"此时左边界为"<<leftB<<"右边界为"<<rightB<<"每小时吃的香蕉数为"<<mid<<endl;while(leftB<rightB){long long tar=0;mid=(leftB+rightB)/2;for(int i:piles){tar+=((i/mid)+((i%mid)?1:0));}if(tar>h){//  cout<<"此时左边界为"<<leftB<<"右边界为"<<rightB<<"每小时吃的香蕉数为"<<mid<<"小时数是"<<tar<<endl;leftB=mid+1;}else{//cout<<"此时左边界为"<<leftB<<"右边界为"<<rightB<<"每小时吃的香蕉数为"<<mid<<"小时数是"<<tar<<endl;rightB=mid;}}mid=(leftB+rightB)/2;return mid;}
};

DEBUG

1

剪枝判断写反了,应当是堆数大于小时数时,就退出,写成如果堆数小于时就退出

2

第二个是二分判断条件写错了,应当是tar>h是不满足条件的,写成了tar>=h,导致会丢掉可行解,而丢掉的可能正是最优解

=的时候是满足条件的,应当保留

除零错误

期望的最小左值一开始设定的是sum/h,如果sum<h的时候,就会使左值为0,
sum<h就是说每小时只吃一个都戳戳有余,如果保留了左值0,那么1肯定满足条件,但是会接着去尝试为0的情况,从而导致了错误

两种解决方法,一种是规定左值最小值为1,另一种就是提前剪枝,如果左值为0,就直接返回1即可

就分析性能而言,应当是提前剪枝的效果更好

3(Mid+1)判断?

产生了死循环
就是tar=h的情况,满足条件且只剩两个值的情况,是保留缩减右侧,尝试继续向左边找结果,那么mid就不应该+1,因为+1就是向右侧去尝试,
而只剩两个值的时候,应当尝试一下左边的,如果继续尝试右边的,就会陷入right=mid,保持死循环;而如果尝试一下左边的,满足条件,就会使right=mid,动了右侧;不满足,就是Left=mid+1.动了左侧,从而避免了死循环
如果是+1的话,就是在除法取到0.5的时候去向上取整
如果不+1,就是有0.5时向下取整
这个取整方向应该和搜索范围缩减的方向相匹配,不然就会导致死循环
如果不满足条件时是left+1,mid是向增大的方向增加,说明向右是满足条件的,此时或许应该不该+1,即尝试左端的left是否满足条件,否则可能会

看只剩最后两个值时的情况,即到底是保留左值还是右值,如果+1就是保留左值,不加就是保留右值
如果陷入了死循环,在+1的情况,说明是去取了右值,
陷入死循环说明此时的值肯定是满足条件的,但是取值的方向和满足条件的方向保持了一致

总结一下就是考虑只剩两个值时候的取值倾向,满足条件时,到底是继续向左还是向右去找值,如果是向左找值,就不应当+1;如果是向右找值,就应当+1;
这个题满足条件就是小时数<=h,速度越快则小时数越小,在满足条件时,应当向左侧找值,所以就不应该+1

1

https://leetcode.cn/problems/maximum-candies-allocated-to-k-children/description/
k个小孩,每个小孩要的糖果数量要一样,如果是n,那么糖果总数就是nk
如果糖果总数和sum小于nk,则必然无解
最好的情况必然是sum/k,是每个小孩能平分到的最大糖果数
每堆数量设为x,

搜索空间是每个小孩分的糖果数,每次搜索的判断是这个糖果数对应出来的堆数
显然每个小孩分的糖果数越多,那么分出来的堆数是越小的,
目标值在搜索空间的从左到右是递减的
那么这样的话,如果搜索值对应到的堆数是比k小的,那么应当是尝试去左侧去找,即让分的糖果数变少,从而增大堆数
目的是要搜索空间的右值,越向右则分的糖果数越多,堆数越少
如果某个区间右值对应中值出来的堆数满足要求,那么还是应当往右靠
如果不满足的话,说明不够,此时应当往左靠
堆数小于k时,应当去

DEBUG

1

第一个错是因为没有考虑如果一开始左边界和右边界就是0的情况,这样的话就不会开启循环,那最后输出的mid,就是没有值的,一个随机值

解决方法

就是在一开始的时候加一个判断,如果左和右都是0的话,直接退出,不返回Mid了,或着让mid一开始就为0,反正也不会进入while循环里,mid也不会被设新值

2

在这里插入图片描述

第二个是因为再次写的时候的一个小聪明,即while退出的条件从leftB<=rightB改为leftB<rightB,考虑的是==的时候必然是要退出循环的,但是<=的时候,在循环内部判断的话,可以给mid赋新值,是只有这个值对应的Mid的值
而如果是<的话,当相等的时候,是直接退出while循环的,而mid没有更新,还是之前的旧值

解决方法

要么最后的时候,即退出while循环后mid再一个赋值等式
要么还是写为<=,在while里判断是否相等
但是性能的话应该是第一种好,因为<=的话会让每次循环都多一个if判断

3

一个致命错误是算堆数的时候是让mid/i,但应该是让i/mid

4

一个致命错误是惯性思维,还是按着如果满足要求就保留右边界right=mid,不满足要求就让left=mid+1的方向去写
但这种写法是只适用于在搜索空间中从左到右,目的值是递增的情况
因为>=k是目的值满足条件的,此时right=mid,相当于在满足条件的基础上进一步缩小搜索空间,以寻找代价更小的解
而<k是不满足条件的,此时需要向满足条件的方向去寻找,left=mid+1就是去剔除掉左侧不满足条件的所有解与mid这个解

当从左到右,目的值是递减的情况时,如果满足条件还保留right=mid,虽然此时的mid时满足条件的,但是相当于自行截掉了右侧所有可能依然满足条件且代价更小的解
如果不满足条件让left=mid+1,则更是荒谬,因为此时mid都不满足了,继续向右找,更是完全找不到
相反,此时应当是满足条件时,保留左侧的这个可行解,而尝试向右侧去找代价更小的解,即满足条件时left=mid,不满足时,向左侧去找,right=mid-1

5

又一个致命错误是死循环的产生
在这里插入图片描述
在这里插入图片描述

在这种样例下,满足条件,保留left不动,那么left一直不动,right也不动,从而造成死循环
在从左到右目的值是递增情况下不会出现这种情况,是因为除法是向下取整的
而这种情况下,由于是向下取整,满足时还left不动,就会导致最后区间只有两个相邻的值,但是/完后是0.5,不会进1,导致一直取下值,造成死循环

中值写为
mid=(leftB+rightB+1)/2
在这里插入图片描述

class Solution {
public:int maximumCandies(vector<int>& candies, long long k) {long long sum=0;for(int i:candies){sum+=i;}int leftB=0;int rightB=sum/k;int mid=0;while(leftB<rightB){long long res=0;mid=(leftB+rightB+1)/2;for(int i:candies){res+=(i/mid);}if(res<k){cout<<"此时左边界为"<<leftB<<"右边界为"<<rightB<<"糖果数为"<<mid<<"分的堆数是"<<res<<endl;rightB=mid-1;}else{cout<<"此时左边界为"<<leftB<<"右边界为"<<rightB<<"糖果数为"<<mid<<"分的堆数是"<<res<<endl;leftB=mid;}}mid=(leftB+rightB)/2;return mid;}
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/439233.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

windows中下载、安装、配置JDK/JDK环境配置/Java配置环境变量/Linux中安装配置JDK环境

JDK下载(官网)、安装、配置(包括系统、idea、eclipse)一篇就够了 1、问题概述? Java开发者必须掌握的JDK下载、安装、配置过程。 包括在Eclipse及IDEA中的配置使用 2、下载JDK 【注册Oracle官网账号】 下载的前天是注册orcle官网账号,作为开发者,这个必须有,随时关注…

VBA信息获取与处理第三个专题第三节:工作薄在空闲后自动关闭

《VBA信息获取与处理》教程(版权10178984)是我推出第六套教程&#xff0c;目前已经是第一版修订了。这套教程定位于最高级&#xff0c;是学完初级&#xff0c;中级后的教程。这部教程给大家讲解的内容有&#xff1a;跨应用程序信息获得、随机信息的利用、电子邮件的发送、VBA互…

Web安全 - 路径穿越(Path Traversal)

文章目录 OWASP 2023 TOP 10导图定义路径穿越的原理常见攻击目标防御措施输入验证和清理避免直接拼接用户输入最小化权限日志监控 ExampleCode漏洞代码&#xff1a;路径穿越攻击案例漏洞说明修复后的安全代码代码分析 其他不同文件系统下的路径穿越特性Windows系统类Unix系统&a…

记录|Modbus-TCP产品使用记录【摩通传动】

目录 前言一、摩通传动实验图1.1 配置软件 IO_Studio1.2 测试软件Modbus Poll1.2.1 读写设置测试1.2.2 AI信号的读取 1.3 对应的C#连接Modbus的测试代码如下【自制&#xff0c;仅供参考】1.4 最终实验图 更新时间 前言 参考文章&#xff1a; 自己需要了解和对比某些产品的Modbu…

【MySQL】服务器管理与配置

MySQL服务器 服务器默认配置 查看服务器默认选项和系统变量 mysqld --verbose --help 查看运行时的系统变量&#xff0c;可以通过like去指定自己要查询的内容 状态变量的查看 系统变量和状态变量的作用域 全局作用域&#xff1a; 对于每个会话都会生效当前会话&#xff1a;只…

初识算法 · 滑动窗口(1)

目录 前言&#xff1a; 长度最小的子数组 题目解析 算法原理 算法编写 无重复长度的最小字符串 题目解析 算法原理 算法编写 前言&#xff1a; 本文开始&#xff0c;介绍的是滑动窗口算法类型的题目&#xff0c;滑动窗口本质上其实也是双指针&#xff0c;但是呢&#…

异常处理【C++提升】(基本思想,重要概念,异常处理的函数机制、异常机制,栈解旋......你想要的全都有)

更多精彩内容..... &#x1f389;❤️播主の主页✨&#x1f618; Stark、-CSDN博客 本文所在专栏&#xff1a; C系列语法知识_Stark、的博客-CSDN博客 座右铭&#xff1a;梦想是一盏明灯&#xff0c;照亮我们前行的路&#xff0c;无论风雨多大&#xff0c;我们都要坚持不懈。 异…

828华为云征文|华为云Flexus云服务器X实例搭建部署H5美妆护肤分销商城、前端uniapp

准备国庆之际&#xff0c;客户要搭个 H5 商城系统&#xff0c;这系统好不容易开发好啦&#xff0c;就差选个合适的服务器上线。那可真是挑花了眼&#xff0c;不知道哪款性价比高呀&#xff01;就像在琳琅满目的选择前。最终慧眼识珠&#xff0c;选择了华为云 Flexus X。至于为什…

redis高级篇 抢红包案例的设计以及分布式锁

一 抢红包案例 1.1 抢红包 二倍均值算法&#xff1a; M为剩余金额&#xff1b;N为剩余人数&#xff0c;公式如下&#xff1a; 每次抢到金额随机区间&#xff08;0&#xff0c;&#xff08;M/N&#xff09;*2&#xff09; 这个公式&#xff0c;保证了每次获取的金额平均值…

TX-LCN框架 分布式事务

一、三种事务模式 1&#xff09;LCN 基于XA协议&#xff0c;事务提交或回滚的操作由事务管理服务器统一告诉它管理的多个项目&#xff0c;也就是说在A事务&#xff0c;B事务的事务提交操作或回滚操作都是在同一时刻发生&#xff0c;并且要么都提交&#xff0c;要么都回滚。 LCN…

低代码可视化-UniApp二维码可视化-代码生成器

市面上提供了各种各样的二维码组件&#xff0c;做了一简单的uniapp二维码组件&#xff0c;二维码实现依赖davidshimjs/qrcodejs。 组件特点 跨浏览器支持&#xff1a;利用Canvas元素实现二维码的跨浏览器兼容性&#xff0c;兼容微信小程序、h5、app。 无依赖性&#xff1a;QR…

数据库(MySQL):使用命令从零开始在Navicat创建一个数据库及其数据表(一).创建基础表

一. 使用工具和命令 1.1 使用的工具 Navicat Premium 17 &#xff1a;“Navicat”是一套可创建多个连接的数据库管理工具。 MySQL版本8.0.39 。 1.2 使用的命令 Navicat中使用的命令 命令命令解释SHOW DATABASES&#xff1b;展示所有的数据库CREATE DATABASE 数据库名称; 创…

震动传感器介绍及实战

目录 前言 震动传感器 1.震动传感器配图 2.震动传感器原理图 3.震动传感器使用 1-震动传感器的意义 2-震动传感器的应用场景 3- SW-18010P震动传感器使用方法 震动传感器控制灯 操作 增加延时 使用SPC-ISP生成演示函数 总结 前言 我们上节已经简单了解了LED的使用…

【机器学习】音乐生成——AI如何创作个性化音乐与配乐

我的主页&#xff1a;2的n次方_ 音乐是人类文化的重要组成部分&#xff0c;它具有极强的情感表达和艺术价值。近年来&#xff0c;随着人工智能技术的飞速发展&#xff0c;AI已经能够自动生成音乐&#xff0c;甚至根据用户需求创作个性化配乐。AI生成音乐的应用场景广泛&…

redis中的数据类型(Set与ZSet)

&#xff08;一&#xff09;set set在我们目前有两个意思&#xff0c;首先就是这里使用的集合&#xff0c;第二个是我们的set和get方法 因为set是一个集合&#xff0c;所以他具有集合的一些特点&#xff1a; 1.集合中的元素无序 2.集合中的元素是不可重复的 3.集合间是可…

5G NR物理信号

文章目录 NR 物理信号与LTE的区别上行参考信号DMRS (UL)SRSPT-RS(UL) 下行参考信号DMRS(DL)PT-RS(DL)CSI-RSPSSSSS NR 物理信号与LTE的区别 用SSS、CSI-RS和DMRS 取代了CRS信号。下行业务信道采用TM1波束赋形传输模式。基于SSB 或者CSI-RS进行RSRP和SINR测量。基于DMRS 进行共…

【Mybatis篇】Mybatis的关联映射详细代码带练 (多对多查询、Mybatis缓存机制)

&#x1f9f8;安清h&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;【计算机网络】,【Mybatis篇】 &#x1f6a6;作者简介&#xff1a;一个有趣爱睡觉的intp&#xff0c;期待和更多人分享自己所学知识的真诚大学生。 目录 &#x1f3af;一.关联映射概述 &#x1f6a…

2024.9.29 问卷数据分析

最近拿到了一份受众回访的问卷数据&#xff0c;排到的任务是对它进行数据探索。 其实对于问卷数据的处理我只在参加正大杯那次做过&#xff08;正大杯拿了校三&#xff09;&#xff0c;可见这个处理水平还有待提高&#xff08;当然是各种原因促成的结果&#xff09;&#xff0…

17 链表——21. 合并两个有序链表 ★

17 链表 21. 合并两个有序链表 将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1: 输入:l1 = [1,2,4], l2 = [1,3,4] 输出:[1,1,2,3,4,4] 算法设计: 合并两个有序链表,并保持有序性,可以采用迭代法和递归法两种…

卸载WSL(Ubuntu),卸载linux

禁用 WSL 功能 打开 Windows 功能&#xff1a; 按下 Windows R 打开运行对话框&#xff0c;输入 optionalfeatures&#xff0c;然后按回车。 禁用 WSL&#xff1a; 在弹出的 Windows 功能窗口中&#xff0c;找到 适用于 Linux 的 Windows 子系统&#xff08;Windows Subsystem…