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

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;
}

相关文章:

  • 分布式GPU上计算长向量模的方法
  • 2.脚本文件初识
  • python 如何把元组拆成几个包并输出
  • 智诚科技苏州SOLIDWORKS授权代理商的卓越之选
  • 单片机-89C51部分:6、按键
  • 组件之间的信息传递的四种方法!!【vue3 前端】
  • 自然语言处理之机器翻译:Statistical Machine Translation(SMT)的评估方法解析与创新实践
  • 从零开始开发一个简易的五子棋游戏:使用 HTML、CSS 和 JavaScript 实现双人对战
  • 3、Linux操作系统下,linux的技术手册使用(man)
  • 杨洋出席青岛啤酒白啤品牌活动 共赴生活美学之旅
  • 高自由度与多功能指尖设计:Allegro灵巧手V5(4F Plus)的技术亮点
  • CSS元素动画篇:基于当前位置的变换动画(四)
  • 技术分享 | Oracle-RAC修改IP信息
  • 【博客系统】博客系统第一弹:博客系统项目配置、MyBatis-Plus 实现 Mapper 接口、处理项目公共模块:统一返回结果、统一异常处理
  • 如何将数据输入到神经网络中
  • 小刚说C语言刷题——1320时钟旋转
  • AIGC(生成式AI)试用 32 -- AI做软件程序测试 3
  • 疑难解析 | 解决金仓数据库中securecmdd服务连接报错“Permission denied“问题
  • 初步自定义layui的table(laravel 12)
  • C盘清理实用技巧整理
  • 海南儋州市委副书记任延新已赴市人大常委会履新
  • 黄仁勋访华期间表示希望继续与中国合作,贸促会回应
  • 屋顶上的阳光与火光:战争如何改变了加沙的能源格局
  • 南阳市委原书记朱是西被“双开”:搞劳民伤财的“政绩工程”
  • 永辉超市一季度净利降近八成,未来12个月至18个月是改革成果集中释放期
  • 美联储报告披露关税战冲击波:消费信心下降,经济担忧加深