zoukankan      html  css  js  c++  java
  • Codeforces Round #543题解

    A题

    题意比较难懂,其实就是查一下他给的k个哪些不是学校的最大值

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    const int N=1e5+10;
    struct node{
        int x,id;
        bool operator <(const node &t) const{
            return x<t.x;
        }
    }s[N];
    vector<int> num;
    int mx[N];
    int main(){
        int n,m,k;
        cin>>n>>m>>k;
        int i;
        for(i=1;i<=n;i++){
            cin>>s[i].x;
        }
        for(i=1;i<=n;i++){
            cin>>s[i].id;
            mx[s[i].id]=max(mx[s[i].id],s[i].x);
        }
        int cnt=0;
        for(i=1;i<=k;i++){
            int x;
            cin>>x;
            if(mx[s[x].id]!=s[x].x){
                cnt++;
            }
        }
        cout<<cnt<<endl;
    }
    View Code

    B题

    这题我做的时候写了个高复杂度的算法,就是先枚举二维再找

    但是其实观察到题目性质,本题每个数都不相同,因此直接桶维护两和,直接对两和出现最多的取max

    这是因为每个数都不同,所以加起来相同的两数,一定都是不同的

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    const int N=2e5+10;
    int a[N];
    int s[N];
    int main(){
        ios::sync_with_stdio(false);
        int n;
        cin>>n;
        int i,j;
        for(i=1;i<=n;i++){
            cin>>a[i];
            s[a[i]]++;
        }
        sort(a+1,a+1+n);
        int ans=0;
        for(i=1;i<=n;i++){
            for(j=i+1;j<=n;j++){
                int cnt=0;
                int x=a[i]+a[j];
                cnt=2;
                int l=i+1;
                for(int k=l;k<j;k++){
                    if(x-a[k]<0)
                        continue;
                    if(a[k]&&s[x-a[k]])
                        cnt++;
                }
                ans=max(ans,cnt/2);
            }
        }
        cout<<ans<<endl;
    }
    View Code

    C题

    这题是一道模拟题,我采用的是方法就是枚举时间点,然后观察所有队列里面的情况,如果已经结束,那么放新的进去,注意判断k>n以及所有的都已经放进去的情况

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    const int N=1e5+10;
    int a[N];
    int id[N];
    int s[N],vis[N];
    int main(){
        ios::sync_with_stdio(false);
        int n,k;
        cin>>n>>k;
        int i;
        for(i=1;i<=n;i++){
            cin>>a[i];
        }
        int cnt=0;
        int pos=0;
        for(i=1;i<=k&&i<=n;i++){
            s[i]=a[i];
            id[i]=i;
        }
        pos=i;
        int ans=0;
        for(int tim=1;tim<=150000;tim++){
            if(cnt==n)
                break;
            for(i=1;i<=k&&i<=n;i++){
                if(s[i]<=0)
                    continue;
                int x=(int)(1.0*cnt/n*100+0.50);
                //cout<<x<<" "<<a[id[i]]-s[i]+1<<endl;
                if(x==a[id[i]]-s[i]+1){
                    if(!vis[id[i]]){
                        vis[id[i]]=1;
                        ans++;
                    }
                }
            }
            for(i=1;i<=k&&i<=n;i++){
                s[i]--;
                if(s[i]==0){
                    cnt++;
                    if(pos<=n){
                        id[i]=pos;
                        s[i]=a[pos];
                        pos++;
                    }
                }
            }
        }
        cout<<ans<<endl;
    }
    View Code

    D题

    这道题我思考的想法和正解的思路是一样的,我们只要找到一个合法区间,那么就能先删完前面,再删中间,看看总共是否符合情况

    但是我忘了一点,虽然暴力是n^2的,但是显然随着左端点的变化,右端点一定至少不会后退,因此使用双指针算法,其实就是线性复杂度,没必要右端点也重来

    之后就是用一个桶维护信息比较,注意有个问题,我写的时候又没考虑到,因为s<k,所以会产生,我们枚举的区间不到k长度就已经完成任务,此时只要删前面就行了。

    我写的时候遗漏了这个情况,会wa12,因为按照我这种写法,当满足条件的时候,右指针不会再向右移,因此我无法做到把小区间扩展成合法的大区间,其实只要与0取个max即可

    关键细节看代码

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    const int N=5e5+10;
    int n,m,k,s;
    int a[N],b[N];
    int sum[N];
    int d[N];
    int tmp[N];
    vector<int> num;
    int main(){
        ios::sync_with_stdio(false);
        cin>>m>>k>>n>>s;
        int i,j;
        for(i=1;i<=m;i++){
            cin>>a[i];
        }
        int cnt=0;
        for(i=1;i<=s;i++){
            cin>>b[i];
            if(++d[b[i]]==1){
                cnt++;
            }
        }
        int r=0;
        int now=0;
        for(i=1;i<=m;i++){
            while(r<m&&now<cnt){
                r++;
                sum[a[r]]++;
                if(sum[a[r]]==d[a[r]]){//满足要求的多了一个
                    now++;
                }
            }
            if(now==cnt){
                int l=(i-1)%k;
                if(((i-1)/k+(m-r)/k)>=(n-1)){
                    cout<<l+max((r-i+1-k),0)<<endl;
                    int sign=max((r-i+1-k),0);
                    for(j=1;j<=l;j++){
                        cout<<j<<" ";
                    }
                    for(int x=i;x<=r&&sign;x++){
                        if(sum[a[x]]>d[a[x]]){
                            --sum[a[x]];
                            sign--;
                            cout<<x<<" ";
                        }
                    }
                    return 0;
                }
            }
            if(--sum[a[i]]==d[a[i]]-1)
                now--;
        }
        cout<<-1<<endl;
        return 0;
    }
    View Code

    E题

    带补

    F题

    套路题,维护lcs来分两种情况讨论dp更新状态

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    const int N=1e5+10;
    string s;
    int f[5050];
    int lcs[5050][5050];
    int main(){
        ios::sync_with_stdio(false);
        int n,a,b;
        cin>>n>>a>>b;
        cin>>s;
        s=" "+s;
        for(int i=1;i<=n;++i){
            f[i]=f[i-1]+a;
            for(int j=1;j<i;j++){
                if(s[i]==s[j]) lcs[i][j]=lcs[i-1][j-1]+1;
                if(lcs[i][j]!=0&&i-j>=lcs[i][j]) f[i]=min(f[i],f[i-lcs[i][j]]+b);
            }
        }
        cout<<f[n]<<endl;
    }
    View Code
    没有人不辛苦,只有人不喊疼
  • 相关阅读:
    NOIP2011 D1T1 铺地毯
    NOIP2013 D1T3 货车运输 倍增LCA OR 并查集按秩合并
    POJ 2513 trie树+并查集判断无向图的欧拉路
    599. Minimum Index Sum of Two Lists
    594. Longest Harmonious Subsequence
    575. Distribute Candies
    554. Brick Wall
    535. Encode and Decode TinyURL(rand and srand)
    525. Contiguous Array
    500. Keyboard Row
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/14152426.html
Copyright © 2011-2022 走看看