• [Codeforces #211] Tutorial


    Link:

    Codeforces #211 传送门

    一套非常简单的题目,但很多细节都是错了一次才能发现啊……

    还是不能养成OJ依赖症,交之前先多想想corner case!!!

    A:

    模拟,要特判0啊

    #include <bits/stdc++.h>
    
    using namespace std;
    #define X first
    #define Y second
    typedef long long ll;
    typedef double db;
    typedef pair<int,int> P;
    int n;
    void solve(int x)
    {
        if(x<5) printf("O-|");
        else printf("-O|");
        if(x>=5) x-=5;
        for(int i=1;i<=x;i++) printf("O");
        printf("-");
        for(int i=1;i<=4-x;i++) printf("O");
        puts("");
    }
    
    int main()
    {
        scanf("%d",&n);
        if(!n) solve(0);//特判0! 
        while(n) solve(n%10),n/=10;
        return 0;
    }
    Problem A

    B:

    模拟,范围是$1.5*1e5$!!!仔细读题啊

    #include <bits/stdc++.h>
    
    using namespace std;
    #define X first
    #define Y second
    typedef long long ll;
    typedef double db;
    typedef pair<int,int> P;
    int n,k,cur,dat[150005];P res;
    //范围是1.5*1e5!
    int main()
    {
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++) scanf("%d",&dat[i]);
        for(int i=1;i<=k;i++) cur+=dat[i];
        res.X=1;res.Y=cur;
        for(int i=1;i<=n-k;i++)
        {
            cur-=dat[i];cur+=dat[i+k];
            if(res.Y>cur) res.Y=cur,res.X=i+1;
        }
        printf("%d",res.X);
        return 0;
    }
    Problem B

    C:

    string.erase和vector.erase一样,尽量不要用

    期望复杂度是$O(n)$级别的

    此题为了支持删除我还手写了个链表……

    其实不用两次扫描+删除+输出,只要扫一遍,边扫边判断当前字母能否加入答案就行了

    #include <bits/stdc++.h>
    
    using namespace std;
    #define X first
    #define Y second
    typedef long long ll;
    typedef double db;
    typedef pair<int,int> P;
    const int MAXN=2e5+10;
    char s[MAXN];int len,k,nxt[MAXN];
    
    int main()
    {
        scanf("%s",s+1);len=strlen(s+1);
        for(int i=1;i<=len;i++) nxt[i]=i+1;
        k=1;nxt[len+1]=len+1;
        while(nxt[nxt[k]]!=len+1)
            if(s[k]==s[nxt[k]]&&s[nxt[k]]==s[nxt[nxt[k]]])
                nxt[k]=nxt[nxt[k]];
            else k=nxt[k];
        k=1;
        while(nxt[nxt[nxt[k]]]!=len+1)
            if(s[k]==s[nxt[k]]&&s[nxt[nxt[k]]]==s[nxt[nxt[nxt[k]]]])
                nxt[nxt[k]]=nxt[nxt[nxt[k]]];
            else k=nxt[k];
        k=1;
        while(k!=len+1) printf("%c",s[k]),k=nxt[k];
        return 0;
    }
    Problem C

    D:

    答案的可行性具有单调性,明显可以二分

    由于使用自己的钱数为$a-sum p_i$,和哪些人参与购买无关

    因此每次判断时可以采取贪心的策略

    1、选择拥有钱数最多的$k$个人和价格最低的$k$个车购买

    2、为了使额外挪用的钱数不超过$a$,人和车从小到大排序后一一对应明显是最优的选择

    最后要特判$sum p_ile a$的情况,此时直接减会出现负数,因此要用最终答案和0取max!!!

    #include <bits/stdc++.h>
    
    using namespace std;
    #define X first
    #define Y second
    typedef long long ll;
    typedef double db;
    typedef pair<int,int> P;
    const int MAXN=1e5+10;
    int n,m,a,p[MAXN],b[MAXN];ll pre[MAXN];
    
    bool check(int x)
    {
        ll sum=0;
        for(int i=1;i<=x;i++)
            if(b[n-x+i]<p[i]) sum+=p[i]-b[n-x+i];
        return sum<=a;
    }
    
    int main()
    {
        scanf("%d%d%d",&n,&m,&a);
        for(int i=1;i<=n;i++) scanf("%d",&b[i]);
        for(int i=1;i<=m;i++) scanf("%d",&p[i]);
        sort(b+1,b+n+1);sort(p+1,p+m+1);
        for(int i=1;i<=m;i++) pre[i]=pre[i-1]+p[i];
        
        int l=0,r=min(m,n);
        while(l<=r)
        {
            int mid=(l+r)>>1;
            if(check(mid)) l=mid+1;
            else r=mid-1;
        }//答案一定要记得取MAX! 
        printf("%d %d",r,max(pre[r]-a,0ll));
        return 0;
    }
    Problem D

    E:

    貌似题解出锅了……

    后面再填吧,其实就是一个预处理+暴力枚举

  • 相关阅读:
    Eclipse MarketPlace 打不开,对话框闪退
    docker 创建容器的时候的坑
    win7 设置docker加速器
    postgres常用命令
    docker加速器配置
    docker 安装 postgresql
    Spring Cloud-服务的注册与发现之服务注册中心(Eureka Server)
    redis incr自增指定的无限期 key 删除问题
    redis读取自增时候指定的key问题
    docker 安装 redis
  • 原文地址:https://www.cnblogs.com/newera/p/9502203.html
Copyright © 2020-2023  润新知