• Codeforces Round #402 (Div. 2)


    做了一套模拟contest,前三道题顺风顺水,第四道题卡懵逼了,不应该不应该。

    A - Pupils Redistribution

    题目大意:有两组,每组里面都有n个人,每个人都有一个评价分数1到5,你每次能从两组人中

    分别挑选一个人,然后交换,问你使两组人每个分数评价的人都相同最少需要交换多少次。不能完成

    输出-1。

    思路:统计每组需要多少人需要到对面去,再除2就好了。

    #include<bits/stdc++.h>
    using namespace std;
    int vis[2][6];
    int n;
    int main()
    {
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            int g; scanf("%d",&g);
            vis[0][g]++;
        }
        for(int i=1;i<=n;i++)
        {
            int g; scanf("%d",&g);
            vis[1][g]++;
        }
        int ans=0;
        for(int i=1;i<=5;i++)
        {
            int sum=vis[1][i]+vis[0][i];
            if(sum&1)
            {
                puts("-1");
                return 0;
            }
            ans+=sum/2-min(vis[1][i],vis[0][i]);
        }
        if(ans&1) puts("-1");
        else cout<<ans/2<<endl;
        return 0;
    }
    View Code

    B - Weird Rounding

    题目大意:给你一个数n 和 一个数 k ,要求删除n中个位数中的某几个,使其能被 10^k 整除,问你

    最少删除几个数。

    思路:直接模拟,从最低位开始。

    #include<bits/stdc++.h>
    using namespace std;
    char s[20];
    int k;
    int main()
    {
        scanf("%s %d",s,&k);
        int len=strlen(s);
        int ans=0,cnt=0;
        for(int i=len-1;i>=0;i--)
        {
            if(s[i]=='0') cnt++;
            if(cnt==k) break;
            if(s[i]!='0') ans++;
        }
        if(cnt==k) printf("%d
    ",ans);
        else printf("%d
    ",len-1);
        return 0;
    }
    View Code

    C - Dishonest Sellers

    题目大意:有一个商店有n个商品,价格分别为p1[ i ],1天后的价格为p2[ i ],你今天必须买 k 件商品

    1天后把剩下没买过的全部买掉,问你最少花费多少钱。

    思路:简单贪心,先将差价排序,前k个必取,后面的如果价差为负就取。

    #include<bits/stdc++.h>
    using namespace std;
    const int N=2*1e5+5;
    struct node
    {
        int c,id;
        bool operator < (const node &t)const
        {
            return c<t.c;
        }
    }w[N];
    int a[N],b[N],n,k;
    bool vis[N];
    int main()
    {
        cin>>n>>k;
        for(int i=0;i<n;i++) scanf("%d",&a[i]);
        for(int i=0;i<n;i++) scanf("%d",&b[i]);
        for(int i=0;i<n;i++) w[i].c=a[i]-b[i],w[i].id=i;
        sort(w,w+n);
        int ans=0;
        for(int i=0;i<n;i++)
        {
            if(i<k || w[i].c<0) ans+=a[w[i].id],vis[w[i].id]=1;
        }
        for(int i=0;i<n;i++)
        {
            if(!vis[i]) ans+=b[i];
        }
        cout<<ans<<endl;
        return 0;
    }
    View Code

    D - String Game

    题目大意:给你两个字符串 t 和 p 且 | t | > | p |,现在我们要按给定的顺序一个一个地拿掉 t 中的字符,

    问你最大拿掉几个字符,p 还是 t 的子序列。 

    我模拟contest的时候一直看错题意,以为这个子序列的意思是,必须连在一起。还有就是我把这个题

    想的太麻烦了,我刚开始想的时候如果将 t 的字符一个一个拿掉很难判断目前为止到底是不是最大值,

    所以我就想从后往前一个一个按顺序插入,第一次碰到满足的情况就是答案了,然后还傻逼一样地写

    了一个链表。。。。。。。。。。。我他妈我都服了我自己了,连二分搜索都不会了。。。。。。。

    思路:直接二分最大值,可以O( n )地判断当前的 t 序列的子序列中有没有 p ,我们可以用一个w[ i ]

    数组表示,第 i 个数是第几个被拿掉的。

    #include<bits/stdc++.h>
    using namespace std;
    const int N=2*1e5+5;
    char t[N],p[N];
    int a[N],w[N],n,m;
    bool check(int x)
    {
        int j=1;
        for(int i=1;i<=n;i++)
        {
            if(w[i]>x && t[i]==p[j]) j++;
        }
        if(j>m) return true;
        else return false;
    }
    int main()
    {
        scanf("%s%s",t+1,p+1);
        n=strlen(t+1); m=strlen(p+1);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            w[a[i]]=i;
        }
        int l=0,r=n,ans=0;
        while(l<=r)
        {
            int mid=(l+r)>>1;
            if(check(mid))
            {
                ans=max(ans,mid);
                l=mid+1;
            }
            else r=mid-1;
        }
        cout<<ans<<endl;
        return 0;
    }
    View Code

     ps : 满足某种条件的最大值最小值,优先考虑二分!!!!!!!!!!!!!

  • 相关阅读:
    Unity3D性能优化--- 收集整理的一堆
    Unity5.3官方VR教程重磅登场-系列7 优化VR体验
    VR沉浸体验的要求
    Unity5中叹为观止的实时GI效果
    浅谈控制反转与依赖注入[转]
    unity 使用unityaction 需要注意的问题[转]
    c# orm框架 sqlsugar
    unity Instantiate设置父级物体bug
    宝塔面板 使用mongodb注意事项
    unity中gameObject.SetActive()方法的注意事项。
  • 原文地址:https://www.cnblogs.com/CJLHY/p/7307144.html
Copyright © 2020-2023  润新知