当前位置: 首页 > backend >正文

Coding Practice,48天强训(25)

Topic 1:笨小猴(质数判断的几种优化方式,容器使用的取舍)

笨小猴__牛客网

#include <bits/stdc++.h>
using namespace std;bool isPrime(int n) 
{if(n <= 1) return false;if(n <= 3) return true;      // 2和3是质数if(n % 2 == 0 || n % 3 == 0) return false; // 排除2和3的倍数// 只需检查6n±1形式的因数for(int i = 5; i*i <= n; i += 6) {if(n % i == 0 || n % (i+2) == 0) return false;}return true;
}int main() 
{string s; cin >> s;int freq[26] = {0};for (char c : s) freq[tolower(c)-'a']++;int maxn = *max_element(freq, freq+26);int minn = 101;// 最小可能为0, 所以不能用*min_element处理,手写一个for (int n : freq) {if (n > 0 && n < minn) minn = n;}int diff = maxn - minn;if (isPrime(diff)) cout << "Lucky Word\n" << diff;else cout << "No Answer\n0";
}

另外选取几种判断质数的方式,忘了就回来看看

朴素判断:

bool isPrime(int n) {if(n <= 1) return false;         // 1不是质数for(int i = 2; i < n; i++) {    // 检查2到n-1if(n % i == 0) return false; // 能被整除就不是}return true;
}

平方根判断:只需判断到平方根,因为如果n有因数,一定会被分解成<=根号n的两个因数

bool isPrime(int n) {if(n <= 1) return false;for(int i = 2; i*i <= n; i++) {  // i <= sqrt(n)if(n % i == 0) return false;}return true;
}

跳过偶数:除了2,所有偶数都不是质数

bool isPrime(int n) {if(n <= 1) return false;if(n == 2) return true;          // 单独处理2if(n % 2 == 0) return false;     // 排除其他偶数for(int i = 3; i*i <= n; i += 2) { // 只检查奇数if(n % i == 0) return false;}return true;
}

6n+(-)1法则:更高级的数学原理——所有质数(除了2和3)都符合6n±1的形式。即:质数只能是6n+1或6n-1

bool isPrime(int n) {if(n <= 1) return false;if(n <= 3) return true;      // 2和3是质数if(n % 2 == 0 || n % 3 == 0) return false; // 排除2和3的倍数// 只需检查6n±1形式的因数for(int i = 5; i*i <= n; i += 6) {if(n % i == 0 || n % (i+2) == 0) return false;}return true;
}

Topic 2:主持人调度(一)(贪心)

主持人调度(一)_牛客题霸_牛客网

#include <memory>
class Solution {
public:/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可** * @param schedule int整型vector<vector<>> * @return bool布尔型*/struct compare{bool operator()(const vector<int>& a, const vector<int>& b)// 写个比较用的仿函数{return a[1] < b[1]; // a 的结束时间(数组第二个元素) < b 的结束时间,则 a 排在前面}};bool hostschedule(vector<vector<int> >& schedule) {int cl = 0;vector<int> res(schedule.size() * 2);sort(schedule.begin(), schedule.end(), compare());// 对原始数据排序,利用仿函数规则for(const auto& s : schedule){for(const auto& e : s){if(e >= cl) {res.push_back(e);cl = e;}else return false;}}return true;}
};

初步考虑是这样,不过空间上还能优化,不用输出,不用储存,所以可以考虑不用额外的res,直接用下标+[]实现比对

#include <memory>
class Solution {
public:/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可** * @param schedule int整型vector<vector<>> * @return bool布尔型*/struct compare{bool operator()(const vector<int>& a, const vector<int>& b)// 写个比较用的仿函数{return a[1] < b[1]; // a 的结束时间(数组第二个元素) < b 的结束时间,则 a 排在前面}};bool hostschedule(vector<vector<int> >& schedule) {sort(schedule.begin(), schedule.end(), compare());// 对原始数据排序,利用仿函数规则int cl = schedule[0][1];// 最早那个活动的结束时间for(int i = 1; i < schedule.size(); ++i)// 从第二次活动开始遍历其结束时间{if(schedule[i][0] < cl) return false;// 本次活动开始时间和上一次结束时间对比,<意味着有时间冲突,return falsecl = schedule[i][1];}return true;}  
};

Topic 3:分割等和子集

分割等和子集_牛客题霸_牛客网

其实是01背包的一个变体,推荐做这题之前先去把01背包和滚动数组的两题先写了

带你学透0-1背包问题!| 关于背包问题,你不清楚的地方,这里都讲了!| 动态规划经典问题 | 数据结构与算法_哔哩哔哩_bilibili

关于01背包的dp[i][j]的dp含义我觉得卡尔讲的还不是特别清楚,这里我选取了另一位老师的解法

这个我觉得相对清晰,在这题中,dp[i][j]表示从0-i个数中选出的元素,最后总和为j

然后如果是有重量和价值的01背包,dp[i][j]就表示从0-i个物品中选出总重为j的物品,并且这些物品有最多的价值

所以dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i])就可以理解成,最后的i我不选,因为我之前i-1时,背包容量j已经凑够了,所以是dp[i - 1][j]。最后的i我选,意味着j还没凑够,所以j此时就是j - weight[i],刚好还能容纳最后那个i,此时再加上它的价值就是dp[i - 1][j - weight[i]] + value[i]

然后再用滚动数组将二维压缩成一维,以示例1为例,以下是滚动数组的模拟过程,实际上就是用一个一维数组不断刷新并累加数据,这里注意滚动数组一定要倒着遍历,从前遍历的数据会影响后续的结果,会重复相加;

我既是现在的我,也是下一次行动中之前的我

#include <iostream>
#include <vector>
using namespace std;int main() 
{// 抽象为01背包问题,题目中数组元素相当于物品,其重量和价值都是元素的值// 抽出的数之和 = 剩下数之和 = 总数/2 = 背包容量// 如果找到有物品能够装满背包容量,也就意味着这个数组可以取出若干个数,使得取出的数之和和剩下的数之和相同// 状态转移方程:dp[j] = max(dp[j], dp[j - weight[i]] + value[i])//             dp[j] = max(dp[j], dp[j - nums[i]] + nums[i])  重量和价值都是元素的值// 一维记得要倒序遍历,两层循环不能颠倒,先物品后重量,二维无所谓int n, sum = 0; cin >> n;vector<int> nums(n);for(int i = 0; i < n; ++i) {cin >> nums[i];sum += nums[i]; // 读取数组元素并计算总和sum}if (sum % 2 != 0) // 如果总和sum为奇数,直接输出false,因为无法均分{cout << "false";return 0;}int target = sum / 2; // 计算目标和target,即总和的一半vector<int> dp(target + 1, 0);// 初始化动态规划数组dp,dp[j]表示容量为j的背包能装的最大价值// 这里价值和重量都是nums[i],所以dp[j]表示能否凑出和为j的子集for(int i = 0; i < nums.size(); i++) {for(int j = target; j >= nums[i]; j--) // 倒序遍历,防止重复计算{dp[j] = max(dp[j], dp[j - nums[i]] + nums[i]);// 状态转移方程:不选择当前数字或选择当前数字}}if (dp[target] == target) cout << "true";// 如果dp[target]等于target,说明可以凑出和为target的子集else cout << "false";return 0;
}

http://www.xdnf.cn/news/2561.html

相关文章:

  • [Jupyter Notebook]:Jupyter Notebook 安装教程(代码编辑器)
  • 【C++底层】底层的编译逻辑和过程
  • OnlyOffice Document Server 开发版:连接器使用-ARM和x86双模式安装指南
  • C盘清理实用技巧整理
  • 卡洛诗西餐厅,以“中式西餐”为核心战略
  • 如何理解promise 续一
  • 准确--如何在 Windows 上安装并管理多个 Python 环境
  • 【SpringMVC文件上传终极指南:从基础配置到云存储集成】
  • 在亚马逊云服务器上部署WordPress服务
  • Pikachu靶场-目录遍历
  • WPF-遵循MVVM框架创建图表的显示【保姆级】
  • 【学习笔记】计算机操作系统(一)—— 操作系统引论
  • dify实际开发中遇见的几个小问题
  • 基于ART光学跟踪系统打造具有开创性的人车互动VR解决方案
  • 产品经理面经(1)
  • 使用Nestjs, Bun 和 NCC 打造高效的 Node.js 应用构建流程
  • Shell脚本-while循环应用案例
  • Python入门基础
  • w~嵌入式C语言~合集4
  • 深度解析:Web Crawling与Web Scraping的区别与联系
  • 数据结构二叉树与二叉搜索树c实现代码
  • SVT-AV1源码分析-函数svt_aom_motion_estimation_kernel
  • 解决Keil/MDK无法跳转(go to define)问题
  • 2025年AEJ SCI2区:增强麻雀搜索算法CERL-SSA+工业物联网感知通信,深度解析+性能实测
  • SpringBoot配置RestTemplate并理解单例模式详解
  • layui获取无法获取表单数据,data.field一直为空
  • SPL 量化 复权数据
  • 双指针算法(2)——复写零
  • GAMES202-高质量实时渲染(Real-Time Shadows)
  • STM32 CAN通信 HAL库实战教程:从零到测试成功