ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

关于优先队列的一点细节

2022-08-11 03:01:34  阅读:180  来源: 互联网

标签:优先 stu 队列 学号 学生 int 细节 读入 id


主要是关于存储数据的细节

直接上题目:

 

T1

一名老师希望知道他所在的班级成绩最好的同学的名字和学号。但是他所在的班级,人员调动很频繁,经常有学生转入或转出。因此,他需要你的帮助。

输入格式:

第一行读入一个数n(n≤105)表示有n次人员调动或成绩询问。
接下来n行,每行读入的第一个数o。
若o为0表示老师询问班级里总成绩最高的学生的姓名和学号。
若o为1,则再读入一个正整数id表示新入班的学生学号,再读入一个正整数score表示该学生的总成绩,最后再读入一个字符串name表示该学生的姓名。
若o为2,则再读入一个正整数id(id≤105)表示学号为id的学生离开了班级。若班级内没有这个学生,则忽略这个操作。

输出格式:

当老师询问班级里总成绩最高的学生的姓名和学号时,输出该学生的姓名与学号, 姓名和学号用一个空格隔开。
如果此时班里没有学生,则输出"NO STUDENTS"(输出引号内的部分)。
如果有多人总成绩相同,则输出学号最小的那个学生的信息。

 

T2

这是一个模板题,用来模拟堆的功能,也可以用priority_queue来实现。

有3种操作,向集合中添加一个数,删除集合中最小的数,询问集合中最小的数是多少。初始时集合为空。

输入格式:

第一行读入一个数n(1≤n≤105)。
第二行到第n+1行,每行读入一个数o表示哪一种操作。
若o=0,则表示询问集合中最小的数是多少。
若o=1,则表示删除集合中最小的数(若集合为空,忽略此次操作即可)。
若o=2,则再读入一个正整数x表示向集合中添加一个数x,x在int类型范围内。

输出格式:

每一个询问输出一行,表示最小的数的值。
若询问时集合为空,则输出"EMPTY!"(引号里面的内容)。

 


 

个人观点

两题都可以用优先队列解决

 

区别在于,T1的相同数据(学生)多次读入而没有pop()删除时,应视为同一个数据,不要重复存储在优先队列中

如学生A连续入班两次,只记录一次

 

T2的相同数据读入时,必须当做不同对象存储在队列中

如两次读入数字3,队列中应为 3 3

 


 

上代码:

T1(3行注释中文为易错点  注释的代码不重要)

#include<bits/stdc++.h>

using namespace std;
struct student{
    int id,sc,i;
    bool flag;
    string name;
    bool operator >(const student s) const{
        return (sc>s.sc)||(sc==s.sc&&id<s.id);
    }
    bool operator <(const student s) const{
        return (sc<s.sc)||(sc==s.sc&&id>s.id);
    }
}stu[100086];
bool flag[100086];
 
int main(){
    priority_queue<student,vector<student>,less<student> > q;
    int n,o,idd;
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&o);
        
        if(!o){
            while(!q.empty()&&!flag[q.top().id])//每次循环的必要条件:队列非空 
                q.pop();
            if(q.empty()) cout<<"NO STUDENTS"<<endl;
            else cout<<q.top().name<<" "<<q.top().id<<endl;
        }
        //if(!o)中顺序很重要 如果在while中把队列清空,还需要再输出 NO STUDENTS
        else if(o==1){
            scanf("%d %d",&stu[i].id,&stu[i].sc);
            cin>>stu[i].name;
            flag[stu[i].id]=1;
//            stu[i].flag=0;
//            stu[i].i=i;
            q.push(stu[i]);
        }
        else if(o==2){
            scanf("%d",&idd);
            flag[idd]=0;//id与i不同!!! 
//            stu[idd].flag=1;
//            q.push(stu[idd]);
//            cout<<q.top().id<<" "<<q.top().name<<" "<<q.top().flag<<endl;
        }
        
    }
    return 0;
}

T2

 

#include<bits/stdc++.h>
using namespace std;
int main(){
    priority_queue<int,vector<int>,greater<int> > pq;
    int n,tmp,m;
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&tmp);
        
        if(!tmp){
            if(pq.empty()) printf("EMPTY!\n");
            else printf("%d\n",pq.top());
        }
        
        else if(tmp==1){
            if(!pq.empty()) pq.pop();
        }
        
        else if(tmp==2){
            scanf("%d",&m);
            pq.push(m);
        }
        
    }
    return 0;
}

 

 

 

以上。

标签:优先,stu,队列,学号,学生,int,细节,读入,id
来源: https://www.cnblogs.com/wang0302/p/16574536.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有