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
    没有人不辛苦,只有人不喊疼
  • 相关阅读:
    【转载自酷壳】编程能力与编程年龄
    xcode中的nslog数据格式
    xcode 的 pch 预编译头文件
    获取App的Documents路径
    使用gdb调试app
    收集的一些OC知识点
    收集到的几篇看雪学院文章
    【转】iOS平台的应用程序调试与分析
    前端技术开发的一些建议
    UIImage的两种加载方式
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/14152426.html
Copyright © 2011-2022 走看看