【力扣周赛】第350场周赛

  • 2739. 总行驶距离
    • 题目描述
    • 解题思路
  • 2740. 找出分区值
    • 题目描述
    • 解题思路
  • 2741. 特别的排列
    • 题目描述
    • 解题思路

2739. 总行驶距离

题目描述

描述:卡车有两个油箱。给你两个整数,mainTank 表示主油箱中的燃料(以升为单位),additionalTank 表示副油箱中的燃料(以升为单位)。

该卡车每耗费 1 升燃料都可以行驶 10 km。每当主油箱使用了 5 升燃料时,如果副油箱至少有 1 升燃料,则会将 1 升燃料从副油箱转移到主油箱。

返回卡车可以行驶的最大距离。

注意:从副油箱向主油箱注入燃料不是连续行为。这一事件会在每消耗 5 升燃料时突然且立即发生。

示例 1:

输入:mainTank = 5, additionalTank = 10
输出:60
解释:
在用掉 5 升燃料后,主油箱中燃料还剩下 (5 - 5 + 1) = 1 升,行驶距离为 50km 。
在用掉剩下的 1 升燃料后,没有新的燃料注入到主油箱中,主油箱变为空。
总行驶距离为 60km 。

示例 2:

输入:mainTank = 1, additionalTank = 2
输出:10
解释:
在用掉 1 升燃料后,主油箱变为空。
总行驶距离为 10km 。

提示:

1 <= mainTank, additionalTank <= 100

解题思路

难度:简单。

思路:最直观的想法是,使用distance表示可以行驶的最大距离,当主油箱油量小于5时,直接返回mainTank*10,反之当主油箱油量大于等于5时,将distance加以50,再判断副油箱油量,如果副油箱油量大于等于1,则将副油箱油量减去1,同时将主油箱油量减去5再加上1,反之当副油箱油量小于1,则将主油箱油量减去5,最后退出循环后,还需要将distance加上剩余主油箱油量乘以10。

class Solution {
public:int distanceTraveled(int mainTank, int additionalTank) {int distance=0;if(mainTank<5)return mainTank*10;while(mainTank>=5){distance+=50;//有余量if(additionalTank>=1){additionalTank-=1;mainTank-=4;}//无余量elsemainTank-=5;}distance+=mainTank*10;return distance;}
};

总结:模拟,最主要的是注意边界条件。

2740. 找出分区值

题目描述

描述:给你一个 正 整数数组 nums 。

将 nums 分成两个数组:nums1 和 nums2 ,并满足下述条件:

数组 nums 中的每个元素都属于数组 nums1 或数组 nums2 。
两个数组都 非空 。
分区值 最小 。
分区值的计算方法是 |max(nums1) - min(nums2)| 。

其中,max(nums1) 表示数组 nums1 中的最大元素,min(nums2) 表示数组 nums2 中的最小元素。

返回表示分区值的整数。

示例 1:

输入:nums = [1,3,2,4]
输出:1
解释:可以将数组 nums 分成 nums1 = [1,2] 和 nums2 = [3,4] 。
- 数组 nums1 的最大值等于 2 。
- 数组 nums2 的最小值等于 3 。
分区值等于 |2 - 3| = 1 。
可以证明 1 是所有分区方案的最小值。

示例 2:

输入:nums = [100,1,10]
输出:9
解释:可以将数组 nums 分成 nums1 = [10] 和 nums2 = [100,1] 。
- 数组 nums1 的最大值等于 10 。
- 数组 nums2 的最小值等于 1 。
分区值等于 |10 - 1| = 9 。
可以证明 9 是所有分区方案的最小值。

提示:

2 <= nums.length <= 105
1 <= nums[i] <= 109

解题思路

难度:中等。

思路:最直观的想法是,找出差值最小的两个数。首先将数组排序,然后遍历一遍求最小差值。

class Solution {
public:int findValueOfPartition(vector<int>& nums) {//先排序sort(nums.begin(),nums.end());//再找中间两个int n=nums.size();int diff=INT_MAX;for(int i=n-1;i>0;i--){diff=min(diff,nums[i]-nums[i-1]);}return diff;}
};

总结:有时候,题目思路很简单,但是会对题目进行很强的包装,从而产生迷惑性,故此时需要好好分析题目的本质是什么。

2741. 特别的排列

题目描述

描述:给你一个下标从 0 开始的整数数组 nums ,它包含 n 个 互不相同 的正整数。如果 nums 的一个排列满足以下条件,我们称它是一个特别的排列:

对于 0 <= i < n - 1 的下标 i ,要么 nums[i] % nums[i+1] == 0 ,要么 nums[i+1] % nums[i] == 0 。
请你返回特别排列的总数目,由于答案可能很大,请将它对 109 + 7 取余 后返回。

示例 1:

输入:nums = [2,3,6]
输出:2
解释:[3,6,2] 和 [2,6,3] 是 nums 两个特别的排列。

示例 2:

输入:nums = [1,4,3]
输出:2
解释:[3,1,4] 和 [4,1,3] 是 nums 两个特别的排列。

提示:

2 <= nums.length <= 14
1 <= nums[i] <= 109

解题思路

难度:中等。

特别的排列:最直观的想法是,状态压缩DP+记忆化搜索。由于包含n个互不相同的整数,故此时数值下标即唯一代表数值,那么我们可以只记录下标,而不用记录具体的数值。由于是全排列,故每一个元素要么为选要么为不选,对于可选的集合,我们可以将集合映射到二进制位运算中进行计算,比如0、2、3对应数值1101。全集为(1<<n)-1,总个数为(1<<n),将元素从集合中删除是left^(1<<i),判断集合中是否包含该元素则为(left>>i)&1。即从头到尾遍历数组,并将当前元素从可选集合中删除,然后统计在可选集合中且上一个数是i的可选方案,该统计方法即再次遍历数组,选择当前未被使用的且满足要求的元素。(整体思想回溯)

const int MOD=1e9+7;
int specialPerm(vector<int>& nums)
{//只需要记录下标而不需要记录数字int n=nums.size();//将集合对应成二进制数字 left表示可选择的集合 初始为全集 1表示可选择int left=(1<<n)-1; //1<<n表示一共0~(1<<n)-1个大小的数组 第一维度代表的是数字组合 第二维度代表的是当前元素下标int memo[1<<n][n];//记忆化搜索 -1代表未记录过memset(memo,-1,sizeof(memo));//返回值是int类型 两个参数是int类型function<int(int,int)> dfs=[&](int left,int i)->int{//递归出口 没有元素可选 即枚举完了 该排列符合if(left==0)return 1;//有记录则直接返回if(memo[left][i]!=-1)return memo[left][i];int ans=0;//枚举数组下标for(int j=0;j<n;j++){//(left>>j)&1判断当前位是否是1 即枚举该下标是否用过if(((left>>j)&1)&&(nums[j]%nums[i]==0||nums[i]%nums[j]==0))//在left中删除j并继续计算后续ans=(ans+dfs(left^(1<<j),j))%MOD;}memo[left][i]=ans;return ans;};int res=0;for(int i=0;i<n;i++)res=(res+dfs(left^(1<<i),i))%MOD;return res;
}

总结:注意,一般对于集合的元素选择,均可以转换为二进制位运算。

【力扣周赛】第350场周赛相关推荐

  1. 力扣:第 304 场周赛

    力扣:第 304 场周赛 究极手速场 6132.使数组中所有元素都等于零 问题解析 题意:一个数组,你每次可以将数组的值减少一个整数,这个整数小于等于数组的最小正整数,问多少次操作可以将数组全部变为0 ...

  2. 20211201:力扣第268周双周赛(上)

    力扣第268周双周赛(上) 题目 思路与算法 代码实现 写在最后 题目 两栋颜色不同且距离最远的房子 给植物浇水 思路与算法 双指针遍历即可,维护那个索引最大差值即可. 模拟题,正常情况需要每次走一步 ...

  3. 20210119:力扣第42周双周赛(下)

    力扣第42周双周赛(下) 题目 思路与算法 代码实现 写在最后 题目 修改后的最大二进制字符串 得到连续 K 个 1 的最少相邻交换次数 思路与算法 修改后的最大二进制字符串 这道题的思路很简单,交换 ...

  4. 20210101:力扣第42周双周赛(上)

    力扣第42周双周赛(上) 题目 思路与算法 代码实现 写在最后 题目 无法吃午餐的学生数量 平均等待时间 思路与算法 无法吃午餐的学生数量 本题直接暴力模拟也没问题,但是这应该不是题目的本意,我们可以 ...

  5. 20200827:2020力扣第33周双周赛题解

    2020力扣第33周双周赛题解 题目一 示例 解题思路与代码实现 题目二 示例 解题思路与代码实现 题目三 解题思路与代码实现 题目四 示例 解题思路与代码实现 写在最后 题目一 题目一:千位分隔数 ...

  6. 20200727:力扣第31周双周赛题解

    力扣第31周双周赛题解 题目一:在区间范围内统计奇数数目 给你两个非负整数low和high,请你返回low和high之间(包含二者)奇数的数目 0 <= low <= high <= ...

  7. C/C++描述 LeetCode 周赛 第199场周赛(阿里云专场)

    C/C++描述 LeetCode 周赛 第199场周赛(阿里云专场)   大家好,我叫亓官劼(qí guān jié ),在CSDN中记录学习的点滴历程,时光荏苒,未来可期,加油~博主目前仅在CSDN ...

  8. 力扣周赛310场题解

    力扣周赛310场题解 前言 6176. 出现最频繁的偶数元素 6177. 子字符串的最优划分 前言 今天参加了力扣的第310场周赛,也是感觉到了这周的题的一个难度,有些题有想法,但是实际上让我去写的时 ...

  9. 『力扣刷题』5275_找出井字棋的获胜者 解题代码

    LeetCode-cn 力扣刷题 LeetCode-cn力扣刷题目录 165周赛 5275_找出井字棋的获胜者 * 5275. 找出井字棋的获胜者 显示英文描述* 用户通过次数0* 用户尝试次数0* ...

最新文章

  1. Docker的安装和镜像管理并利用Docker容器实现nginx的负载均衡、动静分离
  2. 自定义注解妙用,一行代码搞定用户操作日志记录
  3. Apache Flink 在京东的实践与优化
  4. oracle安装 衍生进程已退出,linux安装oracle 出现问题
  5. QT5开发及实例学习之十Qt5主窗口构成
  6. Android方法的概括,Android_Android中startService基本使用方法概述,Android中有两种主要方式使用Ser - phpStudy...
  7. python-知识回顾-16
  8. 【CCCC】L3-022 地铁一日游 (30分),floyd+大模拟
  9. 基于DEAP库的python进化算法-5.遗传算法求解TSP问题的改进
  10. table 条数过大优化_MySQL数据库优化的介绍(图文)
  11. jQuery实现title提示效果
  12. Google GMS认证测试相关
  13. 互联网财富管理平台应该怎么做?(下篇)
  14. (十四)A Deep Neural Network for Unsupervised Anomaly Detection and Diagnosis in Multivariate Time Seri
  15. adb devices后出现设备offline的解决方法
  16. 数据库期末复习:选择题汇总
  17. 【AAD Connect】01:AAD Connect把本地AD账户同步到Office365(AD域账户迁移)
  18. mysql 查询和修改组合_别崩溃,来看这个MySQL全面瓦解:子查询和组合查询
  19. 获取dataGridView当前行的值
  20. 竞品分析之流程总结以及感悟

热门文章

  1. Linux操作系统源码解读
  2. wince摄像头驱动帖子集锦
  3. unity2d转微信小程序报错
  4. Linux在防火墙中开放SVN端口
  5. ArchSummit深圳2015大会幻灯片开放下载,明星讲师新鲜出炉
  6. 给table表格的tr标签添加圆角效果
  7. waf防护是什么?网站安全防护之waf防护
  8. Bridge网络实现原理
  9. Scrach优秀的58个作品
  10. 学习马士兵教育 GC and Tuning