• priority_queue(优先队列):排序不去重


    C++优先队列类似队列,但是在这个数据结构中的元素按照一定的断言排列有序。

    头文件:#include<queue>

    参数:priority_queue<Type, Container, Functional>,其中Type 为数据类型,Container为保存数据的容器,默认vector,Functional 为元素比较方式,默认升序

          priority_queue<Type>后边两个参数不加,默认为大顶堆

    代码

    含义

    p.push()  

    压入一个元素

    p.pop()

    压出一个元素

    p.top()

    返回优先队列中优先级最高的元素

    p.empty()

    优先队列为空,返回真

    p.size()

    返回优先队列中元素个数

     基础使用方法:

    /*			priority_queue的使用			*/	
    
    #include<iostream>
    #include<queue>
    #include<vector>
    #include<functional>
    using namespace std;
    
    struct nod {
    	int x;
    	int y;
    	nod(int a = 0, int b = 0) :x(a), y(b) {}
    };
    
    
    int main() {
    	int a[10] = { 5,1,3,8,2,4,6,9,0,7 };
    
    
    	/*		大顶堆	vector<int>		*/
    	cout << "
    
    大顶堆	vector<int>:
    ";
    	priority_queue<int>p;		//priority_queue<int,vector<int> > p;
    	for (int i = 0; i < 10; i++)p.push(a[i]);
    	while (!p.empty()) {
    		cout << p.top()<<" ";		
    		p.pop();
    	}
    	//9 8 7 6 5 4 3 2 1 0
    
    
    	/*		大顶堆	pair<int,int>		*/
    	cout << "
    
    大顶堆	pair<int,int>:
    ";		//先比较first,相同的话,比较second
    
    	priority_queue<pair<int, int>>p1;
    	pair<int, int>a1(1, 2);
    	pair<int, int>a2(1, 1);
    	pair<int, int>a3(2, 1);
    	p1.push(a1);
    	p1.push(a2);
    	p1.push(a3);
    	while (!p1.empty()) {
    		cout << p1.top().first << " "<<p1.top().second<<"
    ";
    		p1.pop();
    	}
    	//  2 1
    	//  1 2
    	//  1 1
    
    
    
    	/*		小顶堆	vector<int>			*/
    	cout << "
    
    小顶堆	vector<int>:
    ";
    	priority_queue<int,vector<int>,greater<int> >p2;			//greater<>头文件  #include<functional>
    	for (int i = 0; i < 10; i++)p2.push(a[i]);
    	while (!p2.empty()) {
    		cout << p2.top()<<" ";
    		p2.pop();
    	}
    	//0 1 2 3 4 5 6 7 8 9
    
    
    	/*		小顶堆	pair<int,int>		*/
    	cout << "
    
    小顶堆	pair<int,int>:
    ";		//先比较first,相同的话,比较second
    
    	priority_queue<pair<int, int>,vector<pair<int,int> >,greater<pair<int,int> > >p3;		//定义比较麻烦,别打错了
    	pair<int, int>a4(1, 2);
    	pair<int, int>a5(1, 1);
    	pair<int, int>a6(2, 1);
    	p3.push(a4);
    	p3.push(a5);
    	p3.push(a6);
    	while (!p3.empty()) {
    		cout << p3.top().first << " " << p3.top().second << "
    ";
    		p3.pop();
    	}
    	//  1 1
    	//  1 2
    	//  2 1
    
    	/*		小顶堆	结构体+重载<		*/
    	cout << "
    
    小顶堆	结构体+重载<:
    ";
    	bool operator<(nod a, nod b);
    	priority_queue<nod>p4;			//greater<>头文件  #include<functional>
    	for (int i = 0; i < 10; i++)p4.push(nod(a[i],a[i]+3));
    	while (!p4.empty()) {
    		cout << p4.top().x << " "<<p4.top().y<<"
    ";
    		p4.pop();
    	}
    	/*
    		0 3
    		1 4
    		2 5
    		3 6
    		4 7
    		5 8
    		6 9
    		7 10
    		8 11
    		9 12
    	*/
    	return 0;
    }
    
    bool operator<(nod a, nod b) {
    	return a.x == b.x ? a.y > b.y:a.x > b.x;	//重载<运算符,先比较x,相等在比较y,如果a.y>b.y,返回true,那<成立,所以就是小顶堆
    }
    

    例题:合并果子

    题目描述

    在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。多多决定把所有的果子合成一堆。

    每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和。可以看出,所有的果子经过 n1 次合并之后,就只剩下一堆了。

    多多在合并果子时总共消耗的体力等于每次合并所耗体力之和。

    因为还要花大力气把这些果子搬回家,所以多多在合并果子时要尽可能地节省体力。

    假定每个果子重量都为 1 ,并且已知果子的种类 数和每种果子的数目,你的任务是设计出合并的次序方案,使多多耗费的体力最少,并输出这个最小的体力耗费值。

    例如有 3 种果子,数目依次为 12 , 9 。可以先将 1 、 2 堆合并,新堆数目为 3 ,耗费体力为 3 。

    接着,将新堆与原先的第三堆合并,又得到新的堆,数目为 12 ,耗费体力为 12 。所以多多总共耗费体力3+12=15 。可以证明 15 为最小的体力耗费值。

    输入输出格式

    输入格式:

    共两行。
    第一行是一个整数 n(1n10000) ,表示果子的种类数。

    第二行包含 n 个整数,用空格分隔,第 i 个整数 ai(1ai20000) 是第 i 种果子的数目。

    输出格式:

    一个整数,也就是最小的体力耗费值。输入数据保证这个值小于 2^31

    输入输出样例

    输入样例#1: 
    3 
    1 2 9 
    
    输出样例#1: 
    15
    

    说明

    对于30%的数据,保证有n≤1000

    对于50%的数据,保证有n≤5000

    对于全部的数据,保证有n≤10000

    #include<iostream>
    #include<queue>
    #include <functional>			//greater<>头文件
    using namespace std;
    int main() {
    	int n, a[10010],flag=0;
    	priority_queue<int, vector<int>, greater<int> > p;	//建一个小顶堆
    	cin >> n;
    	for (int i = 0; i < n; i++) {
    		cin >> a[i];
    		p.push(a[i]);
    	}
    	while (p.size() != 1) {				//最后两个相加,然后就把结果压进小顶堆里了,最后里边还有一个就是结果
    		int one = p.top();
    		p.pop();
    		int two = p.top();
    		p.pop();
    		p.push(one + two);
    		flag += one + two;
    	}
    	cout << flag<< "
    ";
    	return 0;
    }
    
  • 相关阅读:
    Python安装(小白教程)中文版Pycharm
    二叉树遍历1
    node* p 和 node *p 和 node * p 的区别
    WinForm中的ListBox组件编程
    C# winform listBox中的项上下移动(转)
    C# ListBox 左移、右移、上移、下移
    C#上移,下移TreeView中的树节点顺序
    C#遍历DataSet与DataSet元素实现代码
    C# 手动编写 DataSet,DataTable 及遍历DataSet中的数据
    【.NET】C#中遍历各类数据集合的方法
  • 原文地址:https://www.cnblogs.com/52dxer/p/10465982.html
Copyright © 2020-2023  润新知