队列及其应用

理性查看,提升自己

问题 K: 连贯子序列
抗病在线,终于搞定了,时间复杂度n^2不让过,优化了半天,终于利用map在nlog下完成了。
我还是太菜了,想不出二分或者队列的方法,dp也不行。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int N=2e5+10,INF=0x3f3f3f3f;
int read() {
    int x=0,f=1;
    char c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}
    while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
    return x*f;
}
void write(int x) {
    if(x<0) putchar('-'),x=-x;
    if(x>9) write(x/10);
    putchar(x%10+'0');
}
int a[200010],vis[200010];



void bu_f(){
    int n=read();

    int id=1;int len=1;
    map<int,int> ma;//umap又快了一倍
    for(int i=1;i<=n;i++){
        a[i]=read();
        ma[a[i]]=1;
        if(ma[a[i]-1]) {
            ma[a[i]]+=ma[a[i]-1];//如果刚好小于1值前面出现,就加上他的贡献
            if(ma[a[i]]>len){//更新
                len=ma[a[i]];
                id=i;
            }
        }
    }
    cout<<len<<'\n';
    cout<<id;
}
int main(){
    //ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    // int t=read();
   int t=1;
    while(t--){
        bu_f();
    }
    return 0;
}

接下来就势如破竹吧

问题 L: 3个数和为0

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int N=2e5+10,INF=0x3f3f3f3f;
int read() {
    int x=0,f=1;
    char c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}
    while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
    return x*f;
}
void write(int x) {
    if(x<0) putchar('-'),x=-x;
    if(x>9) write(x/10);
    putchar(x%10+'0');
}




void bu_f(){
    int n=read();
    vector<int> a(n);
    for(int &v:a) v=read();
    sort(a.begin(),a.end());
    int len=0;
    for(int i=0;i<n;i++)
        for(int j=i+1;j<n;j++){
            auto it=lower_bound(a.begin()+j+1,a.begin()+n,-(a[j]+a[i]));
            if(it!=a.end()&&*it==-(a[j]+a[i])){
                len++;
            }

        }
    if(len) cout<<len;
    else cout<<"No Solution。";
}
int main(){
    //ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    // int t=read();
   int t=1;
    while(t--){
        bu_f();
    }
    return 0;
}

问题 M: 绝对二分

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int N=2e5+10,INF=0x3f3f3f3f;
int read() {
    int x=0,f=1;
    char c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}
    while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
    return x*f;
}
void write(int x) {
    if(x<0) putchar('-'),x=-x;
    if(x>9) write(x/10);
    putchar(x%10+'0');
}




void bu_f(){
    int n=read();
    vector<int> a(n+1);
    map<int,int> ma;
    for(int i=1;i<=n;i++) a[i]=read(),ma[a[i]]=1;
    sort(a.begin()+1,a.end(),[](int x,int y){
        return abs(x)<abs(y);
    });
    int k=read();
    // vector<int> b(k+1);
    for(int i=1;i<=k;i++) {
        int b=read();
        if(!ma.count(b)) {
            cout<<-1<<'\n';
            continue;
        }
        for(int j=1;j<=n;j++){
            if(b==a[j]){
                cout<<j<<'\n';
                break;
            }
        }

    }
}
int main(){
    //ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    // int t=read();
   int t=1;
    while(t--){
        bu_f();
    }
    return 0;
}

问题 N: 正整数分组
很典的题

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int N=1e4+10,INF=0x3f3f3f3f;
int read() {
    int x=0,f=1;
    char c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}
    while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
    return x*f;
}
void write(int x) {
    if(x<0) putchar('-'),x=-x;
    if(x>9) write(x/10);
    putchar(x%10+'0');
}

int a[N];
int n,k;
bool check(LL x){
    int len=1,sum=0;
    for(int i=1;i<=n;i++){
        if(sum+a[i]>x){
            len++;
            sum=a[i];
        }
        else sum+=a[i];
    }
    return len<=k;
}
void bu_f(){
    n=read(),k=read();
    for(int i=1;i<=n;i++) a[i]=read();
    LL l=0,r=1e15+10;
    while(l+1<r){
        LL mid=l+r>>1;
        if(check(mid)) r=mid;
        else l=mid; 
    }
    cout<<r;
}
int main(){
    //ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    // int t=read();
   int t=1;
    while(t--){
        bu_f();
    }
    return 0;
}

问题 O: 计算平均值最大子段

这边卡了一波

ans<sum/k,可以更新,转化ansk<sum
sum是k个a[i]相加
接着转化
k
(a[i]-ans)>0
k个a[i]-ans可以利用前缀和求得,关键是k不知道
可以利用前缀和pre[r]-pre[l],保证r-l>=m

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int N=1e5+10,INF=0x3f3f3f3f;
int read() {
    int x=0,f=1;
    char c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}
    while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
    return x*f;
}
void write(int x) {
    if(x<0) putchar('-'),x=-x;
    if(x>9) write(x/10);
    putchar(x%10+'0');
}

double a[N],b[N],pre[N];
int n,L;
LL sum=0;
bool check(double x){
    double min_left=1e10; //min_left:最小前缀和 
	for (int i=1;i<=n;i++) b[i]=a[i]-x;
	for (int i=1;i<=n;i++) pre[i]=pre[i-1]+b[i];//pre[]:前缀和数组 
	for (int r=L;r<=n;r++) //一个小贪心,从L开始枚举右端点
	{
		min_left=min(min_left,pre[r-L]);//不断更新符合条件的最小前缀和
		if (pre[r]-min_left>=0) return true;
	} 
	return false;
}
void bu_f(){
    n=read(),L=read();
    for(int i=1;i<=n;i++) a[i]=read();
    double l=0,r=1e6,d=1e-5;
    while(r-l>d){
        double mid=(l+r)/2;
        if(check(mid)) l=mid;
        else r=mid; 
    }
    cout<<(int)(1000*r);
}
int main(){
    //ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    // int t=read();
   int t=1;
    while(t--){
        bu_f();
    }
    return 0;
}

问题 P: 中位数(完善程序)

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int N=1000,INF=0x3f3f3f3f;
int read() {
    int x=0,f=1;
    char c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}
    while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
    return x*f;
}
void write(int x) {
    if(x<0) putchar('-'),x=-x;
    if(x>9) write(x/10);
    putchar(x%10+'0');
}
int n,i,lbound,rbound,mid,m,count;
int x[N];



void bu_f(){
    n=read(),m=read();
    for(int i=0;i<n;i++) x[i]=read();
    sort(x,x+n);
    cout<<x[n/2];
    
    
}
int main(){
    //ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    // int t=read();
   int t=1;
    while(t--){
        bu_f();
    }
    return 0;
}

问题 Q: 切割绳子(程序填空)

点击查看代码
#include <iostream>
using namespace std;
int n, m, i,l,r, mid, count,sum;
int len[150];  // 绳子长度
bool check(int x){
    count=0;
    for(int i=1;i<=n;i++){
        count+=len[i]/x;
    }
    return count>=m;
}
int main()
{
    cin >> n;
    count = 0;
    for (i = 1; i <= n; i++)
    {
        cin >> len[i];
        sum+=len[i];
    }
    cin >> m;
    if(sum<m)
    {
        cout << "Failed" <<endl;
        return 0;
    }
    l=0,r=1000000+1;
    while (l+1<r)
    {
        mid = l+r>>1;
        if(check(mid)) l=mid;
        else r=mid;
    }
    cout << l << endl;
    return 0;
}
posted @ 2023-11-24 14:55  不o凡  阅读(24)  评论(0)    收藏  举报