C++知识点总结(57):STL综合

一、数据结构

1. 队列

功能 代码
定义 queue<tp>q
入队 .push(x)
出队 .pop()
队头 .front()
队尾 .back()
为空 .empty()
大小 .size()

2. 映射

功能 代码
定义 map<tp1,tp2>name
增/改 mp[key]=value
删除 .erase(key)
全删 .clear()
头部 .begin()
尾部 .end()
key 出现 .count(key)
为空 .empty()
大小 .size()
查找 .find(key)
it->first
it->second

二、队列例题

1. 约瑟夫环(数据加强)

题目描述

n n n 个人报数,报到 m m m 的人出列,再由下一个人重新从 1 1 1 开始报数,以此类推,输出依次出圈人的编号。

输入描述

一行两个整数 n , m n,m n,m

输出描述

一行 n n n 个整数,相邻整数用一个空格隔开,按顺序输出每个出圈人的编号

样例1

输入

10 3

输出

3 6 9 2 7 1 8 5 10 4

提示

对于 50 % 50\% 50% 的数据, n , m ≤ 50 n,m\le 50 n,m50
对于 80 % 80\% 80% 的数据, n ≤ 1000 , m ≤ 1 0 6 n\le1000,m\le10^6 n1000,m106
对于 100 % 100\% 100% 的数据, 1 ≤ n ≤ 5000 , 1 ≤ m ≤ 1 0 9 1\le n\le5000,1\le m\le10^9 1n5000,1m109

程序1: 暴力

#include<bits/stdc++.h>
using namespace std;
int n,m;
queue<int>q;
int main(){
   
   
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        q.push(i);
    for(int i=1;i<=n;i++){
   
   //一共有n个人需要出圈
        for(int j=1;j<=m-1;j++){
   
   //前1~m-1的人不用出圈
            q.push(q.front());//备份一份本体到队尾
            q.pop();//本体删除
        }
        cout<<q.front()<<" ";//输出出圈人
        q.pop();//出圈人出圈
    }
    return 0;
}

问题:直接模拟会非常耗时,尤其是 m > n m>n m>n 的时候,可以考虑使用模运算作答。

参考答案

#include<bits/stdc++.h>
using namespace std;
int n,m;
queue<int>q;
int main(){
   
   
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        q.push(i);
    for(int i=1;i<=n;i++){
   
   
        for(int j=1;j<=(m-1)%q.size();j++){
   
   //模运算,记得不要直接m%=n
            q.push(q.front());
            q.pop();
        }
        cout<<q.front()<<" ";
        q.pop();
    }
    return 0;
}

2. 打印队列

题目描述

学生会里只有一台打印机,但是有很多文件需要打印,因此打印任务不可避免地需要等待。有些打印任务比较急,有些不那么急,所以每个任务都有一个 1 ∼ 9 1∼9 19 间的优先级,优先级越高表示任务越急。
打印机的运作方式如下:首先从打印队列里取出一个任务 J J J,如果队列里有比 J J J 更急的任务,则直接把 J J J 放到打印队列尾部,否则打印任务 J J J(此时不会把它放回打印队列)。
给定打印队列中各个任务的优先级,以及所关注的任务在队列中的位置(队首位置为 0 0 0),求该任务完成的时刻。所有任务都需要 1 1 1 分钟打印。
例如,打印队列为 { 1 , 1 , 9 , 1 , 1 , 1 } \{ 1,1,9,1,1,1 \} { 1,</

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值