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

10.9 lpf|求凸包|正反扫描

 

 

lc3494

正向模拟,反向倒推更新

 

模拟多名巫师按顺序酿造每瓶药水的过程max

用数组记录巫师完成上一瓶的时间

最终算出酿造所有药水的最短总时间

 

class Solution {

public:

    long long minTime(vector<int>& skill, vector<int>& mana) {

        int n = skill.size();

        vector<long long> last_finish(n); // 第 i 名巫师完成上一瓶药水的时间

 

        for (int m : mana) {

            // 按题意模拟

            long long sum_t = 0;

            for (int i = 0; i < n; i++) {

                sum_t = max(sum_t, last_finish[i]) + skill[i] * m;

            }

            // 倒推:如果酿造药水的过程中没有停顿,那么 lastFinish[i] 应该是多少

            last_finish[n - 1] = sum_t;

            for (int i = n - 2; i >= 0; i--) {

                last_finish[i] = last_finish[i + 1] - skill[i + 1] * m;

            }

        }

        return last_finish[n - 1];

    }

};

 

class Solution {
public:
long long minTime(vector<int>& skill, vector<int>& mana) {
int n = skill.size(), m = mana.size();
vector<int> s(n + 1); // skill 的前缀和
partial_sum(skill.begin(), skill.end(), s.begin() + 1);

        long long start = 0;
for (int j = 1; j < m; j++) {
long long mx = 0;
for (int i = 0; i < n; i++) {
mx = max(mx, 1LL * mana[j - 1] * s[i + 1] - 1LL * mana[j] * s[i]);
}
start += mx;
}
return start + 1LL * mana[m - 1] * s[n];
}
};

凸包

struct Vec {

    int x, y;

    Vec operator-(const Vec& b) { return {x - b.x, y - b.y}; }

    long long det(const Vec& b) { return 1LL * x * b.y - 1LL * y * b.x; }

    long long dot(const Vec& b) { return 1LL * x * b.x + 1LL * y * b.y; }

};

 

class Solution {

    // Andrew 算法,计算 points 的上凸包

    // 由于横坐标(前缀和)是严格递增的,所以无需排序

    vector<Vec> convex_hull(vector<Vec>& points) {

        vector<Vec> q;

        for (auto& p : points) {

            while (q.size() > 1 && (q.back() - q[q.size() - 2]).det(p - q.back()) >= 0) {

                q.pop_back();

            }

            q.push_back(p);

        }

        return q;

    }

 

public:

    long long minTime(vector<int>& skill, vector<int>& mana) {

        int n = skill.size(), m = mana.size();

        vector<int> s(n + 1);

        vector<Vec> vs(n);

        for (int i = 0; i < n; i++) {

            s[i + 1] = s[i] + skill[i];

            vs[i] = {s[i], skill[i]};

        }

        vs = convex_hull(vs); // 去掉无用数据

 

        long long start = 0;

        for (int j = 1; j < m; j++) {

            Vec p = {mana[j - 1] - mana[j], mana[j - 1]};

            // p.dot(vs[i]) 是个单峰函数,二分找最大值

            int l = -1, r = vs.size() - 1;

            while (l + 1 < r) {

                int mid = l + (r - l) / 2;

                (p.dot(vs[mid]) > p.dot(vs[mid + 1]) ? r : l) = mid;

            }

            start += p.dot(vs[r]);

        }

        return start + 1LL * mana[m - 1] * s[n];

    }

};

 

 

lc2584

 

用最小质因数数组来高效处理质因数相关操作,以找到有效的数组分割点

 lpf  是  lowest prime factor (最小质因数)的缩写。

代码的前半部分通过一个循环来初始化  lpf  数组。对于每个数  i ,如果  lpf[i]  还没有被赋值(即  lpf[i] == 0 ),就说明  i  是一个质数。

然后,对于  i  的所有倍数  j (从  i  开始,每次增加  i ),如果  lpf[j]  还没有被赋值,就将  lpf[j]  设为  i 。这样, lpf[j]  就存储了  j  的最小质因数。

(和素数筛一个思想)

在后续处理数组元素的质因数时,会用到  lpf  数组来快速分解每个数的质因数。例如,当分解数  x  时,通过不断除以它的最小质因数(从  lpf[x]  获取),可以逐步得到  x  的所有质因数

  C++ 的版本:

#include <vector>

#include <algorithm>

using namespace std;

 

class Solution {

private:

    const int N = 1000001;

    vector<int> lpf;

 

    void initLPF()

    {

        lpf.resize(N, 0);

        for (int i = 2; i < N; ++i) {

            if (lpf[i] != 0) continue;

            for (int j = i; j < N; j += i) {

                if (lpf[j] != 0) continue;

                lpf[j] = i;

            }

        }

    }

 

public:

    int findValidSplit(vector<int>& nums) {

        initLPF();

        int n = nums.size();

        vector<int> last(N, 0);

        vector<vector<int>> prime(n);

 

        for (int i = 0; i < n; ++i) {

            prime[i] = vector<int>();

        }

 

        for (int i = n - 1; i >= 0; --i) {

            int x = nums[i];

            while (x > 1) {

                int p = lpf[x];

                while (x % p == 0) {

                    x /= p;

                }

                prime[i].push_back(p);

                last[p] = max(last[p], i);

            }

        }

 

        int pos = 0;

        for (int i = 0; i <= n - 2; ++i) {

            for (int p : prime[i]) {

                pos = max(last[p], pos);

            }

            if (pos == i) {

                return i;

            }

        }

        return -1;

    }

};

代码说明

1.  initLPF  函数:

- 用于初始化最小质因数数组  lpf 。通过双重循环,为每个数找到其最小的质因数。

 

2.  findValidSplit  函数:

- 首先调用  initLPF  初始化  lpf  数组。

- 然后定义  last  数组记录每个质因数最后出现的位置, prime  数组存储每个位置上数字的质因数。

- 从后往前遍历数组  nums ,对每个数字分解质因数,并更新  last  数组和  prime  数组。

- 最后从前向后遍历,根据  prime  和  last  数组寻找有效的分割点。

 

lc804

hash

class Solution {
public:
int uniqueMorseRepresentations(vector<string>& words) {
// 哈希表法
int len = words.size();
if(len == 0){
return 0;
}


vector<string> datas = {".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.."};
unordered_set<string> tag;
for(int i = 0; i < len; i ++){
string str;
for(int j = 0; j < words[i].size(); j ++)

      {   //转摩斯
char ch = words[i][j];
if(ch >= 'a' && ch <= 'z')
str += datas[ch - 'a'];
else if(ch >= 'A' && ch <= 'Z')
str += datas[ch - 'A'];
else
return -1;

}
tag.insert(str);
}
return tag.size();
}
};

 

 

http://www.dtcms.com/a/461254.html

相关文章:

  • HashMap 与 Hashtable 深度对比分析
  • 网站开始开发阶段的主要流程辽宁建设工程信息网工程业绩怎么上传
  • 缓存雪崩、击穿、穿透是什么与解决方案
  • 桌面图标又乱了?这个小神器,让你的桌面布局“一键复位”
  • mongodb慢查询优化 速度欻欻滴~
  • 从零开始的C++学习生活 6:string的入门使用
  • 风景网站模板济南seo关键词排名工具
  • UE5 测量 -1,长度测量:P2制作定位球与定位线,P3制作射线检测节点,P4在鼠标位置生成定位球
  • UE5 GAS GameAbility源码解析 EndAbility
  • 潍坊网站建设 潍坊做网站外贸网站服务器推荐
  • 第7章 n步时序差分(3) n 步离轨策略学习
  • 【Leetcode hot 100】35.搜索插入位置
  • Django ORM 字段查询表达式(Field lookup expressions)
  • 设计模式--组合模式:统一处理树形结构的优雅设计
  • 推荐算法学习笔记(十九)阿里SIM 模型
  • 高级网站开发工程师证书现代网站建设
  • 只能在线观看的电影网站咋么做wordpress教程 菜单
  • echarts画一个饼图
  • 基于改进YOLO算法的果园环境中障碍物识别与检测技术研究
  • 三元锂电池和磷酸铁锂电池:从原子晶格到应用哲学的深度解析
  • vscode-background 扩展的原理、配置和使用
  • 2100AI相亲(三)
  • 时钟服务器主地址
  • 瑞安学校网站建设口碑好网站建设价格
  • 自己做的网站访问不了建设网站哪些公司好
  • SpringMVC启动流程
  • HTTP 请求方法与参数上传形式的关系
  • 如何减少 Elasticsearch 集群中的分片数量
  • 当通过API发送请求的方式自动触发Jenkins job报错HTTP Status 403 – Forbidden的解决办法
  • 一个网站如何工作流程建立网站需要哪些手续