写在前面
文章会不定时更新
求三连
正文-队列
队列的定义
定义一定要有
1.队列(queue)是一种特殊的线性数据结构,队列中的元素也是按照入队顺序线性的排列。
2.队列只允许在队列的前端(队头)进行删除操作,后端(队尾)进行插入操作。
3,队列的特点是先进先出(FIFO,First In First Out),即最先入队列的元素最先出队列,就和我们平时排队一样。
队列的实现
队列的基本操作包括入队、出队、判断队列是否为空、求队列中元素的个数(队列长度)等。我们可以用一个数组简单的实现队列的所有操作。
#define MAX_SIZE 100000//定义队列的最大容量
int Queue[MAX_SIZE]//int可以换成其他类型
但是……
in fact 事实上,C++语言的STL库自带了一个队列的实现。这样我们就能简单的实现队列。(不过对于电脑来说,就不是那么容易了)
#include<queue>
queue<int> q;//定义一个数据元素为int的队列
q.push(x);//元素x入队
q.pop();//队头元素出队,但不会返回元素的值
q.front();//返回队头元素
q.back();//返回队尾元素
q.empty();//判断队列是否为空
q.size();//返回队列中元素的个数
队列的应用
1.队列在计算机科学中应用也十分广泛。
2.队列的主要应用是在BFS(广度优先搜索)中。
3.此外,我们要讲的「单调队列」也是队列的重要用途之一。
完结撒花
队列的基础知识就到这里。。。等会可能还有更新。也可能没有……更新的话大概会讲几道题。
第一版更新
前言
今天的更新只弄一个练习题,要不然为啥说是第一版更新呢,就是因为以后还有其他讲解。话说回来栈那一章是不是也应该把更新的标题改成第一版更新
言归正传
在线悲伤氵练习:
【1】P1309 瑞士轮
应该洛谷都有号吧,搜一下就可以了
算法分析: 按比赛规则,每轮比赛先按总分排序,然后对阵,直到R轮比赛结束。
复杂度:R*(2*n)log(2n)
= 50 *(2 * 10^5) * log(2 * 10^5)
≈10^8
🆗,TLE,讲完啦,我们下期再见~~
我只想说。。。什么破梗!!!!!!!
bi——————————————————
咳咳,皮一下很开心~~
言 归 正 传
所以说,需要优化。。
优化:1—2、3—4、…、2i-1—2i.
每组比赛的胜者:赛前,总分是按降序排的;获胜后都得1分,仍是降序;
每组比赛的负者:赛前,总分是按降序排的;不得分,仍是降序。
先按初始分数排序,然后按分数高低两人一组比赛;胜者入队A,负者入队B。这样A、B自身仍是有序的;
合并A、B是O(2n)的,总复杂度O(R2n)=O(10^7) 。
#include<iostream>
#include<algorithm>
using namespace std;
const int N=200005;
int n,m,q;
int id[N],win[N],lose[N],s[N],w[N];
bool player(int a,int b){
if(s[a]!=s[b]){
return s[a]>s[b];
}
return a<b;
}
void merge(){
int i=1,j=1;
id[0]=0;
while(i<win[0]&&j<=lose[0]){
if(player(win[i],lose[j])){
id[++id[0]]=win[i++];
}
else{
id[++id[0]]=lose[j++];
}
}
while(i<=win[0]){
id[++id[0]]=win[i++];
}
while(j<=lose[0]){
id[++id[0]]=lose[j++];
}
}
int main(){
cin>>n>>m>>q;
n=n*2;
for(int i=1;i<=n;i++){
cin>>s[i];
}
for(int i=1;i<=n;i++){
cin>>w[i];
id[i]=i;
}
sort(id+1,id+n+1,player);
for(int i=1;i<=m;i++){
win[0]=lose[0]=0;
for(int j=1;j<=n;j=j+2){
if(w[id[j]]>w[id[j+1]]){
s[id[j]]++;
win[++win[0]]=id[j];
lose[++lose[0]]=id[j+1];
}
else{
s[id[j+1]]++;
win[++win[0]]=id[j+1];
lose[++lose[0]]=id[j];
}
}
merge();
}
cout<<id[q]<<endl;
}
完事收工,古德拜