本文介绍了优先队列在解决特定算法问题中的应用,包括如何使用优先队列进行元素的高效管理和检索,特别是在需要维护一定顺序或查找特定元素的场景下。通过具体的代码示例,展示了如何实现基于优先级的元素插入和删除操作,以及如何利用优先队列解决最大战斗力团队的选取问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

priority_queue是一个优先队列,队列里面按一定的规则排序,每次压入一个元素,都会排序

priority_queue<int,vector<int>,greater<int>> que2;//升序
priority_queue<int,vector<int>,less<int>> que3;//降序
///仅仅一个元素的优先队列

有多个元素的优先队列

struct node//第一种
{
    int x,y;
    bool friend operator < (node a,node b)
    {
        return a.x<b.x;
    }
}ee[1000];
//自定义排序规则

hdu4006

http://acm.hdu.edu.cn/showproblem.php?pid=4006

I表示加入一个数

Q询问第k大的数值

这道题用优先队列做,队列升序

用队首保存第k大的数,第k大数也是k个有序数了最小的数

每次压入后,如果队列元素大于k,就弹出最小的呢个数

ac:

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

int main()
{
    char ctr[2];
    int n,m,d;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        priority_queue<int,vector<int>,greater<int>> que;
        for(int i=0;i<n;i++)
        {
            scanf("%s",&ctr);
            if(ctr[0]=='I')
            {
                scanf("%d",&d);
                que.push(d);
                if(que.size()>m)
                    que.pop();
            }
            else{
                printf("%d\n",que.top());
            }
        }
    }
    return 0;
}

tokitsukaze and Soldier

题意:

在一个游戏中,tokitsukaze需要在n个士兵中选出一些士兵组成一个团去打副本。
第i个士兵的战力为v[i],团的战力是团内所有士兵的战力之和。
但是这些士兵有特殊的要求:如果选了第i个士兵,这个士兵希望团的人数不超过s[i]。(如果不选第i个士兵,就没有这个限制。)
tokitsukaze想知道,团的战力最大为多少

解析:

选择一个人后,从人数大于等于他的人里找s[i]个最大的人

#include<bits/stdc++.h>
#define ll long long
#define MAXN 100005
using namespace std;
struct node
{
    int v,s;
    friend bool operator <(node a,node b)
    {
        return a.s>b.s;
    }
}ee[MAXN];
struct NN
{
    int v;
    friend bool operator <(NN a,NN b)
    {
        return a.v>b.v;
    }
};
 
int main()
{
    int n,j=1;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d%d",&ee[i].v,&ee[i].s);
    sort(ee+1,ee+n+1);
    ll sum=0;
    ll ans=0;
    priority_queue<NN> que;
    for(int i=1;i<=n;i++)//按s[i]从大到小压入元素,队列里当前元素全为大于等于s[i]的
    {                    //优先队列里的是权值小的,优先将权值小的弹出
        sum+=ee[i].v;
        que.push(NN{ee[i].v});
        while(que.size()>ee[i].s)//超出数量弹出
            sum-=que.top().v,que.pop();
        ans=max(ans,sum);
    }
    printf("%lld\n",ans);
    return 0;
}

法2:直接用树状数组二分暴力处理

#include<bits/stdc++.h>
#define lowbit(x) (x)&(-x)
#define ll long long
#define MAXN 100005
using namespace std;
ll s[MAXN],v[MAXN];
vector<ll> vc[MAXN];
ll n;
ll sum[MAXN];
ll num[MAXN];
struct node
{
    ll id,v,s;
    friend bool operator <(node a,node b)
    {
        return a.v>b.v;
    }
}b[MAXN];
 
void add(ll x,ll c)
{
    for(ll i=x;i<=n;i+=lowbit(i))
        sum[i]+=c,num[i]+=1;
}
 
void add2(ll x,ll c)
{
    for(ll i=x;i<=n;i+=lowbit(i))
        sum[i]-=c,num[i]-=1;
}
 
ll query(ll r)
{
    ll ans=0;
    for(ll i=r;i>0;i-=lowbit(i))
        ans+=sum[i];
    return ans;
}
 
ll query2(ll r)
{
    ll ans=0;
    for(ll i=r;i>0;i-=lowbit(i))
        ans+=num[i];
    return ans;
}
 
int main()
{
    scanf("%lld",&n);
    for(ll i=1;i<=n;i++)//每次把小于于s[i]的删除,然后从剩下的里找最大的s[i]个
    {
        scanf("%lld%lld",&v[i],&s[i]);
        b[i]=node{i,v[i],s[i]};
    }
    sort(b+1,b+n+1);
    for(ll i=1;i<=n;i++)
        vc[b[i].s].push_back(i);
 
    for(ll i=1;i<=n;i++)
        add(i,b[i].v);
    ll Res=0;
    for(ll i=1;i<=n;i++)
    {
        if(vc[i].size()==0)
            continue;
        else{
            ll l=1,r=n;
            ll ans=0;
            while(l<=r)
            {
                ll mid=(l+r)>>1;
                ll k=query2(mid);//个数
                if(k<=i)
                {
                    l=mid+1;
                    ans=max(ans,mid);
                }
                else{
                    r=mid-1;
                }
            }
            ll res=query(ans);
            Res=max(res,Res);
            for(ll j=0;j<vc[i].size();j++)
            {
                ll k=vc[i][j];
                add2(k,b[k].v);//位置和值的坐标是反的
            }
        }
    }
    printf("%lld\n",Res);
    return 0;
}

 

资源下载链接为: https://pan.quark.cn/s/22ca96b7bd39 在 IT 领域,文档格式转换是常见需求,尤其在处理多种文件类型时。本文将聚焦于利用 Java 技术栈,尤其是 Apache POI 和 iTextPDF 库,实现 doc、xls(涵盖 Excel 2003 及 Excel 2007+)以及 txt、图片等格式文件向 PDF 的转换,并实现在线浏览功能。 先从 Apache POI 说起,它是一个强大的 Java 库,专注于处理 Microsoft Office 格式文件,比如 doc 和 xls。Apache POI 提供了 HSSF 和 XSSF 两个 API,其中 HSSF 用于读写老版本的 BIFF8 格式(Excel 97-2003),XSSF 则针对新的 XML 格式(Excel 2007+)。这两个 API 均具备读取和写入工作表、单元格、公式、样式等功能。读取 Excel 文件时,可通过创建 HSSFWorkbook 或 XSSFWorkbook 对象来打开相应格式的文件,进而遍历工作簿中的每个 Sheet,获取行和列数据。写入 Excel 文件时,创建新的 Workbook 对象,添加 Sheet、Row 和 Cell,即可构建新 Excel 文件。 再看 iTextPDF,它是一个用于生成和修改 PDF 文档的 Java 库,拥有丰富的 API。创建 PDF 文档时,借助 Document 对象,可定义页面尺寸、边距等属性来定制 PDF 外观。添加内容方面,可使用 Paragraph、List、Table 等元素将文本、列表和表格加入 PDF,图片可通过 Image 类加载插入。iTextPDF 支持多种字体和样式,可设置文本颜色、大小、样式等。此外,iTextPDF 的 TextRenderer 类能将 HTML、
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值