【十九】【C++】 priority_queue简单使用和仿函数

priority_queue文档介绍翻译

优先队列是一种容器适配器,专门设计成其中的第一个元素始终是根据某种严格的弱排序准则最大的元素。

这种上下文类似于堆,其中元素可以在任何时刻插入,而只能检索最大堆元素(在优先队列中顶部的元素)。

优先队列被实现为容器适配器,这些适配器是使用特定容器类的封装对象作为其底层容器的类,提供一组特定的成员函数来访问其元素。元素从特定容器的“后面”弹出,这被称为优先队列的顶部。

底层容器可以是任何标准容器类模板或其他特定设计的容器类。容器必须通过随机访问迭代器进行访问,并支持以下操作:

  • empty()

  • size()

  • front()

  • push_back()

  • pop_back()

标准容器类vectordeque满足这些要求。默认情况下,如果没有为特定优先队列类实例化指定容器类,则使用标准容器vector

需要支持随机访问迭代器,以便始终在内部保持堆结构。容器适配器会在需要时自动调用算法函数make_heappush_heappop_heap来完成这一点。

简单使用

优先队列(Priority Queue)是一种特殊的队列,它的出队顺序是按照元素的优先级决定的,而不是元素进入队列的先后顺序。在C++中,优先队列通常通过STL中的priority_queue容器来实现。priority_queue<queue>头文件中定义,它可以让你轻松地实现一个能够根据元素优先级进行动态排序的队列。

基本操作

插入元素(push):将一个元素添加到优先队列中。

获取顶部元素(top):返回优先级最高的元素,但不从队列中移除它。

删除顶部元素(pop):移除优先级最高的元素。

检查队列是否为空(empty):检查优先队列是否没有任何元素。

获取队列的大小(size):返回优先队列中的元素数量。

示例代码

下面是一个使用priority_queue的基本示例:

 
#include <iostream>
#include <queue>

int main() {
    // 创建一个int类型的优先队列,默认是最大堆
    std::priority_queue<int> pq;

    // 插入元素
    pq.push(30);
    pq.push(10);
    pq.push(20);
    pq.push(5);

    // 循环直到优先队列为空
    while (!pq.empty()) {
        // 打印顶部元素
        std::cout << pq.top() << " ";
        // 移除顶部元素
        pq.pop();
    }

    return 0;
}

最小堆优先队列

默认情况下,C++的priority_queue使用std::less<T>作为比较函数,这意味着它将实现为一个最大堆,优先级最高的(值最大的)元素会被放在队列的前面。

如果你想创建一个最小堆,使得优先级最低的元素先出队,你可以通过传递一个比较函数来实现。例如:

 
#include <iostream>
#include <queue>
#include <vector>
#include <functional>

int main() {
    // 创建一个最小堆优先队列
    std::priority_queue<int, std::vector<int>, std::greater<int>> pq;

    pq.push(30);
    pq.push(10);
    pq.push(20);
    pq.push(5);

    while (!pq.empty()) {
        std::cout << pq.top() << " ";
        pq.pop();
    }

    return 0;
}

优先队列默认创建最大堆

 
/*优先队列默认创建大堆*/
#if 1
#include <iostream>
#include <queue>
#include <vector>
#include <functional>
using namespace std;

void TestPriorityQueue1()
 {
    // 默认按照less方式比较,创建的是大堆
    priority_queue<int> q;
    q.push(5);
    q.push(4);
    q.push(8);
    q.push(1);
    q.push(9);
    q.push(2);
    q.push(6);
    q.push(3);
    q.push(7);
    q.push(0);
    cout << q.size() << endl;
    cout << q.top() << endl;
    
    q.pop();
    q.pop();
    q.pop();
    cout << q.size() << endl;
    cout << q.top() << endl;
 }

int main(){
    TestPriorityQueue1();
 }

#endif

优先队列主动创建最小堆

 
/*优先队列默认创建最小堆*/
#if 1
#include <iostream>
#include <queue>
#include <vector>
#include <functional>
using namespace std;
// greater是STL提供的以大于方式比较两个元素的类模板
 // 在使用时一定要<functional>的头文件
void TestPriorityQueue2()
 {
    // 如果要创建小堆,则元素必须按照大于的方式比较
    priority_queue<int,vector<int>, greater<int>> q;
    q.push(5);
    q.push(4);
    q.push(8);
    q.push(1);
    q.push(9);
    q.push(2);
    q.push(6);
    q.push(3);
    q.push(7);
    q.push(0);
    cout << q.size() << endl;
    cout << q.top() << endl;
    
     q.pop();
    q.pop();
    q.pop();
    cout << q.size() << endl;
    cout << q.top() << endl;
 }

int main(){
    TestPriorityQueue2();
 }

#endif

优先队列日期类创建最大堆

 
/*优先队列日期类最大堆*/
#if 1
#include <iostream>
#include <queue>
#include <vector>
#include <functional>
using namespace std;
class Date
{
public:
    Date(int year, int month, int day)
    : _year(year)
    , _month(month)
    , _day(day)
    {}
    
     bool operator<(const Date& d)const
    {
        return _day < d._day;
    }
    
     bool operator>(const Date& d)const
    {
        return _day > d._day;
    }
    
     void Show()const{
        cout<<_year<<"-"<<_month<<"-"<<_day<<endl;
    }

private:
    int _year;
    int _month;
    int _day;
 };



void TestPriorityQueue3()
 {
    priority_queue<Date> q;
    
     Date d1(2023, 4, 22);
    Date d2(2023, 4, 21);
    Date d3(2023, 4, 23);
    
     q.push(d1);
    q.push(d2);
    q.push(d3);
    
     while (!q.empty()) {
        q.top().Show();
        q.pop();
    }
    
}

int main(){
    TestPriorityQueue3();
 }

#endif

优先队列范围迭代器创建对象

 
/*优先队列范围迭代器创建对象*/
#if 1

#include <iostream>
#include <queue>
#include <vector>
#include <functional>
using namespace std;

void TestPriorityQueue5()
 {
    vector<int> v{ 3,2,7,6,0,4,1,9,8,5 };
    priority_queue<int> q(v.begin(), v.end());
 }
int main(){
    TestPriorityQueue5();
 }

#endif

优先队列日期类创建最小堆

 
/*优先队列日期类创建最小堆*/
#if 1
#include <iostream>
#include <queue>
#include <vector>
#include <functional>
using namespace std;
class Date
{
public:
    Date(int year, int month, int day)
    : _year(year)
    , _month(month)
    , _day(day)
    {}
    
     bool operator<(const Date& d)const
    {
        return _day < d._day;
    }
    
     bool operator>(const Date& d)const
    {
        return _day > d._day;
    }
    
     void Show()const{
        cout<<_year<<"-"<<_month<<"-"<<_day<<endl;
    }
    
private:
    int _year;
    int _month;
    int _day;
 };

void TestPriorityQueue4()
 {
    priority_queue<Date, vector<Date>, greater<Date>> q;
    
     Date d1(2023, 4, 22);
    Date d2(2023, 4, 21);
    Date d3(2023, 4, 23);
    
     q.push(d1);
    q.push(d2);
    q.push(d3);
    
     while (!q.empty()) {
        q.top().Show();
        q.pop();
    }

 }
int main(){
    TestPriorityQueue4();
 }

#endif

自定义判断函数,函数指针

 
/*自定义判断函数,函数指针*/
#if 1
#include <iostream>
#include <queue>
#include <vector>
#include <functional>
using namespace std;
class Date
{
public:
    Date(int year, int month, int day)
    : _year(year)
    , _month(month)
    , _day(day)
    {}
    
     bool operator<(const Date& d)const
    {
        return _day < d._day;
    }
    
     bool operator>(const Date& d)const
    {
        return _day > d._day;
    }
    
     void Show()const{
        cout<<_year<<"-"<<_month<<"-"<<_day<<endl;
    }
    friend bool CompareDate(const Date* left, const Date* right);
    friend class Compare;
private:
    int _year;
    int _month;
    int _day;
 };

bool CompareDate(const Date* left, const Date* right)
 {
    return left->_day < right->_day;
 }

typedef bool (*COM)(const Date* left, const Date* right);

void TestPriorityQueue6()
 {
    priority_queue<Date*, vector<Date*>, COM> q(CompareDate);
    
     Date d1(2023, 4, 22);
    Date d2(2023, 4, 21);
    Date d3(2023, 4, 23);
    
     q.push(&d1);
    q.push(&d2);
    q.push(&d3);
    
     while (!q.empty()) {
        Date* top = q.top(); // 获取优先队列顶部元素
        top->Show();         // 显示日期
        q.pop();             // 移除顶部元素
    }


 }


int main(){
    TestPriorityQueue6();
 }

typedef bool (*COM)(const Date* left, const Date* right);

这行代码定义了一个函数指针类型COM,用于指向一个特定的函数签名。这个签名要求函数接受两个指向Date对象的常量指针作为参数,并返回一个bool类型的结果。在这个上下文中,这样的函数通常用于比较两个Date对象,并根据比较结果(真或假)来排序或做出决策。

具体来说,typedef关键字在C++中用于为现有的类型定义一个新的名称。在这个例子中,它定义了COM作为一种新的类型,这种类型是指向函数的指针,这些函数具有特定的参数列表和返回类型:

  • 参数列表:两个const Date*类型的参数,表示指向常量Date对象的指针。使用指针允许函数不改变原始对象的状态,同时使用const确保函数内部不会修改这些对象。

  • 返回类型:bool,用于表示比较的结果。在排序或其他需要比较的场景中,返回值通常用于指示第一个参数是否在排序顺序上位于第二个参数之前。

priority_queue<Date*, vector<Date*>, COM> q(CompareDate);

这行代码创建了一个 std::priority_queue,其中包含了指向 Date 对象的指针。在这个 priority_queue 的声明中,使用了三个模板参数:

  • 元素类型:Date*,表示队列中存储的元素是指向 Date 对象的指针。

  • 底层容器:std::vector<Date*>,表示优先队列使用 std::vector 来存储这些指针。std::vector 是一个动态数组,适用于几乎所有类型的容器操作,而且在这里特别适合作为优先队列的底层数据结构。

  • 比较类型:COM,这是一个指向函数的指针类型,用于比较两个 Date 对象。在这个上下文中,COM 是通过之前定义的 typedef 创建的,指向一个接受两个 const Date* 类型参数的函数,并返回一个 bool 类型的结果。

接下来的部分 q(CompareDate);priority_queue构造函数调用,它接受一个名为 CompareDate 的函数作为参数。这个函数符合 COM 类型的要求,用于确定队列中元素的优先顺序。在这个例子中,CompareDate 函数基于日期对象的 _day 字段来比较日期,以决定它们在队列中的顺序。

这种方式允许自定义优先队列的排序准则,而不是仅依赖于元素类型的默认比较操作(例如,如果是基本类型或具有定义了 < 运算符的类型)。通过提供自定义比较函数,用户可以控制哪些元素应该被视为优先级更高,这在处理复杂数据类型或有特定排序需求的场合特别有用。

仿函数

在C++中,仿函数(Function Object或Functor)是一个行为类似函数的对象。具体来说,仿函数是通过重载 operator() 运算符的类实例,这让类的实例可以像函数一样被调用。仿函数提供了比普通函数指针更多的灵活性和功能,因为它们可以拥有自己的状态。

仿函数的优点

状态保持:与普通函数不同,仿函数可以有自己的状态。你可以在多次调用之间保持和修改这些状态。

内联调用:仿函数的调用可以被编译器内联,这意味着可以减少函数调用的开销,提高效率。

泛型编程:仿函数可以搭配标准模板库(STL)中的算法和容器使用,非常适合实现自定义的比较逻辑或操作。

示例:自定义比较仿函数

假设你想在 priority_queue 中使用自定义的比较逻辑,可以定义一个仿函数来实现这一点。以下是一个简化的 Date 类仿函数比较的例子:

 
#include <iostream>
#include <queue>
using namespace std;

class Date {
public:
    int year, month, day;
    Date(int y, int m, int d) : year(y), month(m), day(d) {}
};

// 自定义比较仿函数
class CompareDate {
public:
    bool operator()(const Date& lhs, const Date& rhs) const {
        // 比较逻辑:先年后月再日
        if (lhs.year != rhs.year) return lhs.year > rhs.year;
        if (lhs.month != rhs.month) return lhs.month > rhs.month;
        return lhs.day > rhs.day;
    }
};

int main() {
    priority_queue<Date, vector<Date>, CompareDate> pq;

    pq.push(Date(2023, 4, 22));
    pq.push(Date(2023, 5, 21));
    pq.push(Date(2023, 3, 23));

    while (!pq.empty()) {
        Date d = pq.top();
        cout << d.year << "-" << d.month << "-" << d.day << endl;
        pq.pop();
    }

    return 0;
}

在这个例子中,CompareDate 是一个仿函数,它重载了 operator() 来提供 Date 对象的比较逻辑。这个逻辑首先比较年份,如果年份相同,则比较月份,如果月份也相同,最后比较日。这个仿函数可以用作 priority_queue 的比较类型参数,从而定制容器中元素的排列顺序。

优先队列与仿函数结合

 
/*优先队列与仿函数结合*/
#if 1
#include <iostream>
#include <queue>
#include <vector>
#include <functional>
using namespace std;
class Date
{
public:
    Date(int year, int month, int day)
    : _year(year)
    , _month(month)
    , _day(day)
    {}
    
     bool operator<(const Date& d)const
    {
        return _day < d._day;
    }
    
     bool operator>(const Date& d)const
    {
        return _day > d._day;
    }
    
     void Show()const{
        cout<<_year<<"-"<<_month<<"-"<<_day<<endl;
    }
    friend bool CompareDate(const Date* left, const Date* right);
    friend class Compare;
private:
    int _year;
    int _month;
    int _day;
 };

bool CompareDate(const Date* left, const Date* right)
 {
    return left->_day < right->_day;
 }

typedef bool (*COM)(const Date* left, const Date* right);
// 仿函数--函数对象:可以像函数一样使用的对象
class Compare
{
public:
    bool operator()(const Date* left, const Date* right)
    {
        return left->_day < right->_day;
    }
 };

void TestPriorityQueue7()
 {
    Date d1(2023, 4, 22);
    Date d2(2023, 4, 21);
    Date d3(2023, 4, 23);
    
     CompareDate(&d1, &d2);
    Compare com;
    com(&d1, &d2);
    com.operator()(&d1, &d2);
    
     priority_queue<Date*, vector<Date*>, Compare> q;
    q.push(&d1);
    q.push(&d2);
    q.push(&d3);
    
     while (!q.empty()) {
        Date* top = q.top(); // 获取优先队列顶部元素
        top->Show();         // 显示日期
        q.pop();             // 移除顶部元素
    }
 }

int main()
 {
    TestPriorityQueue7();
    return 0;
 }
#endif

对于优先队列比较参数的探究

 
priority_queue<Date*, vector<Date*>, Compare> q;//仿函数
priority_queue<Date, vector<Date>, CompareDate> pq;//仿函数
priority_queue<Date*, vector<Date*>, COM> q(CompareDate);//函数指针
priority_queue<Date, vector<Date>, greater<Date>> q; //默认greater对象

我们发现第三个参数,比较大小的参数,可以有上面三种使用方法。第一个和第二个是一样的,都是仿函数,仿函数本质是对象,和第四个同样是传入对象,而第三个传入的是函数指针。说明第三个参数可以接收函数指针也可以接收对象。

仿函数和函数指针的区别

虽然从表面上看,仿函数(通过类重载的 operator())和函数指针(指向一个具体函数的指针)都可以作为排序准则传递给 std::priority_queue(或其他模板类),它们在底层实现和使用方式上存在一些关键差异:

仿函数(Function Objects):仿函数是通过类实例化的对象,这些对象通过重载 operator() 来实现。它们可以有自己的状态(成员变量)并可以携带更多的上下文信息。在模板参数中传递仿函数类型时,你实际上传递的是一个类型(而非对象实例本身),std::priority_queue 在内部会创建这个类型的实例来进行元素比较。如果需要传递状态或参数给仿函数,你需要在仿函数类中提供相应的构造函数。

函数指针:函数指针是指向函数的指针,它不能携带状态(除非使用全局变量或静态变量,但这通常不是一个好的设计选择)。在模板参数中使用函数指针时,如 COM 类型,你实际上是在传递一个指向函数的指针,这意味着传递的是一个地址值。当你在构造 std::priority_queue 时提供 CompareDate 函数作为参数,你实际上是在提供一个具体的函数指针值。

对象与地址的传递

对于仿函数,你传递的是一个类型,std::priority_queue 使用这个类型在内部构造一个对象实例。这个过程并不涉及显式的地址传递,而是类型信息的传递。

对于函数指针,传递的确实是一个地址值,即函数在内存中的位置。

默认比较对象

当使用如 std::greater<Date> 这样的默认比较对象时,同样是传递了一个类型给 std::priority_queue,它会构造这个类型的实例来进行比较。std::greater<T>std::less<T> 是标准库提供的比较函数对象类型,它们也是通过重载 operator() 实现的。

优先队列创建对象的方式

使用默认比较函数对象

默认情况下,std::priority_queue使用std::less<T>作为其比较函数对象,构造一个最大堆。这意味着没有指定比较函数时,队列中的最大元素将会位于顶部。

 
std::priority_queue<int> pq; // 默认为最大堆,使用 std::less<int> 比较元素

使用标准库比较函数对象

可以通过显式指定比较函数对象(如std::greater<T>)来改变优先队列的排序行为,例如构建一个最小堆。

 
std::priority_queue<int, std::vector<int>, std::greater<int>> minHeap;

使用自定义仿函数

通过定义一个自定义的比较类(仿函数),可以实现更复杂的比较逻辑。该类需要重载operator()

 
class Compare {
public:
    bool operator()(int a, int b) {
        // 自定义比较逻辑
        return a > b; // 示例:构建最小堆
    }
};
std::priority_queue<int, std::vector<int>, Compare> customHeap;

使用函数指针

如果你有一个静态比较函数,也可以将其地址作为优先队列的比较逻辑。这通常适用于简单的比较逻辑或C风格的代码。

 
bool compare(int a, int b) { return a > b; } // 函数指针比较
// 注意:直接使用函数指针作为模板参数在标准的 priority_queue 中不直接支持,需要包装或转换为对象。

结尾

最后,感谢您阅读我的文章,希望这些内容能够对您有所启发和帮助。如果您有任何问题或想要分享您的观点,请随时在评论区留言。

同时,不要忘记订阅我的博客以获取更多有趣的内容。在未来的文章中,我将继续探讨这个话题的不同方面,为您呈现更多深度和见解。

谢谢您的支持,期待与您在下一篇文章中再次相遇!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

为自监督学习重构去噪扩散模型

在这项研究中&#xff0c;作者检验了最初用于图像生成的去噪扩散模型&#xff08;DDM&#xff09;的表示学习能力。其理念是解构DDM&#xff0c;逐渐将其转化为经典的去噪自动编码器&#xff08;DAE&#xff09;。这一解构过程让大家能够探索现代DDM的各个组成部分如何影响自监…

【Docker】Docker Container操作案例 | 综合实战

文章目录 Docker Container操作案例容器的基本操作容器状态迁移容器批量处理技巧容器交互模式attached模式detached模式interactive模式 容器与宿主机内容复制容器自动删除容器自动重启容器环境变量设置容器详情查看容器执行单行命令容器镜像导入导出容器日志查看容器资源查看 …

C++:多态

C&#xff1a;多态 虚函数虚函数语法虚函数重写协变接口继承 多态构成成员函数状态对比抽象类多态原理多继承与多态虚继承与多态 先看到多态的定义&#xff1a; C的多态是指在面向对象程序设计中&#xff0c;允许使用基类的指针或引用来调用派生类的虚函数的特性。这样的调用将…

数据结构-并查集

并查集原理 在一些应用问题中&#xff0c;需要将n个不同的元素划分成一些不相交的集合。开始时&#xff0c;每个元素自成一个 单元素集合&#xff0c;然后按一定的规律将归于同一组元素的集合合并。在此过程中要反复用到查询一 个元素归属于那个集合的运算。适合于描述这类…

阿里云幻兽帕鲁服务器配置4核16G10M带宽够8个人玩吗?玩起来流畅度怎么样?

阿里云幻兽帕鲁服务器配置4核16G10M带宽这个&#xff0c;个人实测下来&#xff0c;五六个人玩是比较流畅的&#xff0c;不过8个人的话&#xff0c;估计会有点卡。如果是8个人的话&#xff0c;我建议选择8核32G那个配置&#xff0c;更加适合一些。 阿里云一键部署幻兽帕鲁详细教…

【lesson57】信号量和生产者消费者模型(环形队列版)

文章目录 信号量概念信号量接口初始化销毁等待发布 基于环形队列的生产者消费者模型编码Common.hLockGuard.hppTask.hppsem.hppRingQueue.hppConProd.cc 信号量概念 POSIX信号量和SystemV信号量作用相同&#xff0c;都是用于同步操作&#xff0c;达到无冲突的访问共享资源目的…

漫漫数学之旅022

文章目录 经典格言数学习题古今评注名人小传- 刘易斯卡罗尔 经典格言 艾丽斯笑着说&#xff1a;“去尝试也毫无用处&#xff0c;一个人无法相信不可能的事情。”——刘易斯卡罗尔&#xff08;Lewis Carroll&#xff09;《艾丽斯梦游仙境&#xff08;Alice in Wonderland&#…

零基础怎么学编程,免费版中文编程工具下载及构件用法教程

零基础怎么学编程&#xff0c;免费版中文编程工具下载及构件用法教程 一、前言 今天给大家分享的中文编程开发语言工具资料如下&#xff1a; 编程入门视频教程链接 http://​ https://edu.csdn.net/course/detail/39036 ​ 编程工具及实例源码文件下载可以点击最下方官网…

基于Python实现Midjourney集成到(个人/公司)平台中

目前Midjourney没有对外开放Api&#xff0c;想体验他们的服务只能在discord中进入他们的频道进行体验或者把他们的机器人拉入自己创建的服务器中&#xff1b;而且现在免费的也用不了了&#xff0c;想使用就得订阅。本教程使用midjourney-api这个开源项目&#xff0c;搭建Midjou…

Linux第55步_根文件系统第2步_测试使用busybox生成的根文件系统

测试使用busybox生成的根文件系统。测试内容较多&#xff0c;很杂。 1、修改“nfs-kernel-server” 1)、打开终端 输入“sudo vi /etc/default/nfs-kernel-server回车”&#xff0c;打开“nfs-kernel-server”文件。 输入密码“123456回车” 见下图&#xff1a; 2)、在最后…

【学网攻】 第(28)节 -- OSPF虚链路

系列文章目录 目录 系列文章目录 文章目录 前言 一、什么是OSPF虚链路&#xff1f; 二、实验 1.引入 实验目标 实验背景 技术原理 实验步骤 实验设备 实验拓扑图 实验配置 扩展 实验拓扑图 实验配置 实验验证 文章目录 【学网攻】 第(1)节 -- 认识网络【学网攻…

模型 4S(满意、服务、速度、诚意)理论

系列文章 分享 模型&#xff0c;了解更多&#x1f449; 模型_总纲目录。重在提升认知。以客户为中心。 1 4S(满意、服务、速度、诚意)理论的应用 1.1 4S 理论在制造业中的应用 某汽车制造企业 A 一直致力于提供高品质的汽车产品和优质的服务&#xff0c;以满足客户的需求和期…

2022年12月电子学会青少年软件编程 中小学生Python编程等级考试二级真题解析(选择题)

2022年12月Python编程等级考试二级真题解析 选择题&#xff08;共25题&#xff0c;每题2分&#xff0c;共50分&#xff09; 1、运行下列程序&#xff0c;最终输出的结果是 info {1:小明,2:小黄,3:小兰} info[4]小红 info[2]小白 print(info) A、{1:小明,2:小白,3:小红,4:小…

高德地图上绘制热力图的方法

百度地图和高德地图的JavaScript API都提供了热力图的绘制方法&#xff0c;都是将热力图作为新的图层&#xff0c;叠加到地图上。但是百度地图的经纬度体系与我们的经纬度存在偏差&#xff0c;高德的与我们相符&#xff0c;应当使用高德地图JavaScript API。 因为是JavaScript…

最长连续手牌 - 华为OD统一考试

OD统一考试&#xff08;C卷&#xff09; 分值&#xff1a; 200分 题解&#xff1a; Java / Python / C 题目描述 有这么一款单人卡牌游戏&#xff0c;牌面由颜色和数字组成&#xff0c;颜色为红、黄、蓝、绿中的一种&#xff0c;数字为 0−9 中的一个。游戏开始时玩家从手牌中…

【题解】差分

差分其实就是前缀和的逆运算。 如果数组 A 是数组 B 的前缀和数组&#xff0c;则称 B 是 A 的差分数组。 思路 由题意得&#xff0c;应该求给定数组的差分数组。 差分加速的原理 对 L 到 R 区间内的数加上 c&#xff0c;时间复杂度是O(c) &#xff0c;即O(n) 。 但是如果…

SORA:OpenAI最新文本驱动视频生成大模型技术报告解读

Video generation models as world simulators&#xff1a;作为世界模拟器的视频生成模型 1、概览2、Turning visual data into patches&#xff1a;将视觉数据转换为补丁3、Video compression network&#xff1a;视频压缩网络4、Spacetime Latent Patches&#xff1a;时空潜在…

NetMizer 日志管理系统 多处前台RCE漏洞复现

0x01 产品简介 NetMizer是提供集成应用交付和应用安全解决方案以实现业务智能网络的优秀全球供应商,为全球企业和运营商提供确保关键业务应用的全面可用性、高性能和完善的安全性的解决方案。 0x02 漏洞概述 NetMizer 日志管理系统position.php、hostdelay.php、等接口处存在…

leetcode刷题--贪心算法

七. 贪心算法 文章目录 七. 贪心算法1. 605 种花问题2. 121 买卖股票的最佳时机3. 561 数组拆分4. 455 分发饼干5. 575 分糖果6. 135 分发糖果7. 409 最长回文串8. 621 任务调度器9. 179 最大数10. 56 合并区间11. 57 插入区间13. 452 用最少数量的箭引爆气球14. 435 无重叠区间…

鸿蒙系统优缺点,能否作为开发者选择

凡是都有对立面&#xff0c;就直接说说鸿蒙的优缺点吧。 鸿蒙的缺点&#xff1a; 鸿蒙是从2019年开始做出来的&#xff0c;那时候是套壳Android大家都知晓。从而导致大家不看鸿蒙系统&#xff0c;套壳Android就是多次一举。现在鸿蒙星河版已经是纯血鸿蒙&#xff0c;但是它的…