• 2019牛客多校第三场


    B Crazy Binary String

    题意

    给一个01字符串,求0和1个数相同的最长子序列和子串长度。

    分析

    子序列长度就是(min(cnt(0),cnt(1))*2),子串的长度也是原题,记录一下0和1个数差的前缀和,然后用一个数组记录前面扫过的0个数和1个数差值的最左位置,前缀和的思想更新答案即可。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int N=1e5+50;
    int n;
    char s[N];
    int cnt[2],mp[2*N];
    int main(void){
    //    freopen("in.txt","r",stdin);
        scanf("%d",&n);
        scanf("%s",s+1);
        int ans1=0,ans2=0;
        memset(mp,-1,sizeof(mp));
        mp[(int)1e5]=0;
        for(int i=1;i<=n;i++){
            cnt[0]+=s[i]=='0';
            cnt[1]+=s[i]=='1';
            if(mp[(int)1e5+cnt[0]-cnt[1]]==-1){
                mp[(int)1e5+cnt[0]-cnt[1]]=i;
            }
            ans1=max(ans1,i-mp[(int)1e5+cnt[0]-cnt[1]]);
        }
        ans2=min(cnt[0],cnt[1])*2;
        printf("%d %d
    ",ans1,ans2);
        return 0;
    }
    

    F Planting Trees

    题意

    给一个矩阵,求出最大的子矩阵满足最大值和最小值之差不超过(m)

    分析

    数据范围给的是(n^3)的做法,对于二维的一个子矩阵,需要(n^2)的时间来枚举上下底,然后使用单调队列维护横向的最大值与最小值之差。

    关键一点在于枚举上下底(i)行和(j)行后,中间的二维矩阵的每一列其实就可以用这一列的最大值和最小值来表示,其他数值都已经无关紧要了,从而转化为一维数组的情况。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int N=505;
    const int INF=0x3f3f3f3f;
    int T,n,m,a[N][N];
    int mx[N],mn[N];
    int mxq[N],mnq[N];
    int main(void){
        scanf("%d",&T);
        while(T--){
            scanf("%d%d",&n,&m);
            for(int i=1;i<=n;i++){
                for(int j=1;j<=n;j++){
                    scanf("%d",&a[i][j]);
                }
            }
            int ans=0;
            //枚举列
            for(int i=1;i<=n;i++){
                for(int j=0;j<=n;j++){
                    mx[j]=0;
                    mn[j]=INF;
                }
                for(int j=i;j<=n;j++){
                    int l=1;
                    int l1=1,r1=0;
                    int l2=1,r2=0;
                    //枚举右边界,维护最小可行左边界
                    for(int r=1;r<=n;r++){
                        mx[r]=max(mx[r],a[r][j]);
                        mn[r]=min(mn[r],a[r][j]);
                        //维护两个单调队列mxq(最大值递减),mnq(最小值递增)
                        while(l1<=r1 && mx[r]>mx[mxq[r1]]){
                            r1--;
                        }
                        mxq[++r1]=r;
                        while(l2<=r2 && mn[r]<mn[mnq[r2]]){
                            r2--;
                        }
                        mnq[++r2]=r;
                        //维护两个单调队列使得max-min<=m
                        while(l<=r && l1<=r1 && l2<=r2 && mx[mxq[l1]]-mn[mnq[l2]]>m){
                            l++;
                            //删去无效元素
                            while(l1<=r1 && mxq[l1]<l){
                                l1++;
                            }
                            while(l2<=r2 && mnq[l2]<l){
                                l2++;
                            }
                        }
                        ans=max(ans,(j-i+1)*(r-l+1));
                    }
                }
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    

    J LRU management

    题意

    模拟题,有(n)次操作,(m)(cache)块,0操作是插入一个块,如果已存在,返回块的值,并将原来的块取出放到队尾,如果不存在,那就插入,并返回插入的值,如果插入后超过(m)个块,队头的块就要出去;1操作是询问某一块或者其上一个或者下一个是否存在,不影响队列结构。

    分析

    学到两个技巧

    • (unordered_map<string,list<pair<string,int> >::iterator> mp)在这道题中很好用,可以直接确定某个块在链表中的位置。
    • 数字串可以转化为(long long)来表示以节省内存,考虑前导零,只需在前面多加一个1。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    unordered_map<string,list<pair<string,int> >::iterator> mp;
    list<pair<string,int> > ls;
    int T,n,m,o,v;
    char s[20];
    int main(void){
        // freopen("in.txt","r",stdin);
        scanf("%d",&T);
        while(T--){
            mp.clear();
            ls.clear();
            scanf("%d%d",&n,&m);
            while(n--){
                scanf("%d%s%d",&o,s,&v);
                if(o==1){
                    auto it=mp.find(s);
                    bool ac=true;
                    int ans=0;
                    if(it==mp.end()){
                        ac=false;
                    }else{
                        //list<int>::iterator
                        auto kv=it->second;
                        if(v==-1){
                            if(kv==ls.begin()){
                                ac=false;
                            }else{
                                kv--;
                                ans=kv->second;
                            }
                        }else if(v==0){
                            ans=kv->second;
                        }else if(v==1){
                            kv++;
                            //end是最末元素指针+1
                            if(kv==ls.end()){
                                ac=false;
                            }else{
                                ans=kv->second;
                            }
                        }
                    }
                    if(ac){
                        printf("%d
    ",ans);
                    }else{
                        printf("Invalid
    ");
                    }
                }else if(o==0){
                    int ans=0;
                    auto it=mp.find(s);
                    if(it!=mp.end()){
                        ans=it->second->second;
                        ls.erase(it->second);
                        ls.push_back({s,ans});
                        auto t=ls.end();
                        t--;
                        it->second=t;
                    }else{
                        ans=v;
                        ls.push_back({s,v});
                        auto t=ls.end();
                        t--;
                        mp[s]=t;
                        if(ls.size()>m){
                            mp.erase(ls.begin()->first);
                            ls.erase(ls.begin());
                        }
                    }
                    printf("%d
    ",ans);
                }
            }
        }
        return 0;
    }
    
  • 相关阅读:
    散户必看 教您怎样在短期内从10万炒到100万
    店主学习篇 如何做服装经营能手
    苹果公司CEO乔布斯在斯坦福大学毕业典礼上的演讲
    手头20万存款的租客 买房划算还是租房省钱?
    把幸福 亲了又亲
    周经理写给公司 的一封信
    土鸡市场前景:
    查看局域网内所有IP
    中国肿瘤年报出炉 浙江每312人就有1人患癌
    中药材喂土鸡或许大家还很疑惑吧
  • 原文地址:https://www.cnblogs.com/zxcoder/p/11258180.html
Copyright © 2020-2023  润新知