60分,求助
查看原帖
60分,求助
367346
Newacfcc2007楼主2022/10/23 19:12

复杂度为O(n*maxk)

码风清奇 不是标准意义上的手工队列

#include<bits/stdc++.h>
#define int long long
#define INF 114514

using namespace std;

inline int read(){
    int _=0,__=1;char ___=getchar();
    while(___>'9'||___<'0'){if(___=='-') __=-1;___=getchar();}
    while(___>='0'&&___<='9'){_=(_<<3)+(_<<1)+___-'0';___=getchar();}
    return __==1?_:-_;
}

inline void write(int _){
    if(!_) return ;
    write(_/10);
    putchar(_%10+'0');
}

int m,n,k,word[1005],cnt=0,ans=0,maxk,mink;
//m,n同程序 k为第二行输入的整数
//word 为记录k值的桶 
//cnt 为队列当中元素的个数
//ans 为查字典次数
//maxk 记录单词k的范围 即word桶的元素个数 
//mink 是最早加入队列的元素 

signed main(){
    m=read();
    n=read();//输入m,n 
    for(int i=1;i<=n;i++){
        k=read();//输入k 
        maxk=max(maxk,k);//开辟word桶空间 
        if(word[k]==0){
            word[k]=i;//入队,word[k]的值为入队编号 
            cnt++;//队列长度+1 
            ans++;//查字典次数+1 
        }
        if(cnt==m){//队列长度达到最大 
            mink=INF;//开始记录入队编号最小的元素 
            for(int j=1;j<=maxk;j++){
                if(word[j]!=0){
                    mink=min(mink,word[j]);
                }
            }//第一遍循环找出队列当中编号最小的元素 
            for(int j=1;j<=maxk;j++){
                if(word[j]==mink){
                    word[j]=0;
                    mink=INF;
                    break;
                }
            }//第二遍循环对编号最小的元素实施出队 
            cnt--;//出队 
        }
    }
    write(ans); 
    return 0;
}
2022/10/23 19:12
加载中...