队列

机器翻译(洛谷P1540)


题目大意

有m个可存放单词和译意的单元,初始内容为空,依次读取文章单词,若在内存单元中不存在则从外存读入,载入内存,若内存数据超过m则最先录入内存单元的出队,直到文章全部翻译完,求外存查找次数。

解题思路

限定了队列容量为m,每当队列中找不到匹配单词时从外存载入,次数+1,超过队列容量时,依据队列FIFO原则。

STL queue
#include<bits/stdc++.h>
using namespace std;
const int N=1e3+5;
bool vis[N];	//记录是否在队列中,降低时间复杂度
int main(){
	int n,m;
	cin>>n>>m;
	queue<int>q;
	int ans=0;
	for(int i=1,k;i<=m;i++){
		cin>>k;
		if(!vis[k]){
			q.push(k);
			ans++;
			if(q.size()>n){	//超出容量出队
				vis[q.front()]=false;	//标记
				q.pop();
			}
		}
		vis[k]=true;
	}
	cout<<ans<<endl;
	return 0;
}
手写循环队列
#include<bits/stdc++.h>
using namespace std;
const int N=1e3+5;
bool vis[N];
struct myque{
    int v[N];
    /*动态分配 int*v; */
    int head,rear;
    bool init(){
        /*动态分配
        v=(int*)malloc(N*sizeof(int);
        if(!v)return false; */
        head=rear=0;
        return true;
    }
    int size(){
        return (rear-head+N)%N;
    }
    bool empty(){
        return size()==0;
    }
    bool push(int x){
        if((rear+1)%N==head)return false;   //队列满
        v[rear]=x;
        rear=(rear+1)%N;
        return true;
    }
    bool pop(int&x){
        if(head==rear)return false; //队列空
        x=v[head];
        head=(head+1)%N;
        return true;
    }
    int front(){
        return v[head];
    }
}Q;
int main(){
    Q.init();
    int n,m;
    cin>>n>>m;
    int ans=0;
    for(int i=1,k;i<=m;i++){
        cin>>k;
        if(!vis[k]){
            ans++;
            vis[k]=true;
            Q.push(k);
            if(Q.size()>n){
                int ret;
                Q.pop(ret);
                vis[ret]=false;
            }
        }
    }
    cout<<ans<<endl;
    return 0;
}

滑动窗口/单调队列(洛谷P1886)


题目大意

对于序列a,用一个长度为k的窗口从左至右按一单位滑动,求出每次滑动后窗口中的最大值,最小值。

解题思路

用单调队列存放窗口中的值对应的原序列下标,本题需要使用两次单调队列,求最大值始终保证队头对应值最大,从队尾更新最值,当值下标超出窗口范围时出队,反之保证最小,输出队头对应值即可。

未知的代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
deque<int>q;
int a[N],n,k;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    cin>>n>>k;
    for(int i=1;i<=n;i++)cin>>a[i];
    for(int i=1;i<=n;i++){
        while(!q.empty()&&a[q.back()]>a[i])q.pop_back();    //更新最小值
        q.push_back(i);
        if(i>=k){
            while(!q.empty()&&q.front()<=i-k)q.pop_front(); //超出范围出队
            cout<<a[q.front()]<<" ";
        }
    }
    cout<<endl;
    q.clear();
    for(int i=1;i<=n;i++){
        while(!q.empty()&&a[q.back()]<a[i])q.pop_back();    //更新最大值
        q.push_back(i);
        if(i>=k){
            while(!q.empty()&&q.front()<=i-k)q.pop_front();
            cout<<a[q.front()]<<" ";
        }
    }
    cout<<endl;
    return 0;
}
posted @ 2023-12-21 20:03  Lost-in-love  阅读(21)  评论(0)    收藏  举报