zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 94 (Rated for Div. 2)(A->E(分治))

    A:http://codeforces.com/contest/1400/problem/A

    解析:

    发现每一个字符串,都包含s[n-1],所以直接打印n个s[n-1]即可

    #include<bits/stdc++.h>
    #include<map>
    #include<iostream>
    #include<cstring>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    const int maxn=1e5+10;
    const int maxn2=1e9+10;
    int answ[maxn];
    int md[maxn];
    int b[maxn];
    int n,m;
    int a[maxn];
    int v[maxn];
    struct node
    {
        int x1,y1,x2,y2;
    }st[maxn];
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {
            int n;
            cin>>n;
            string s;
            cin>>s;
            for(int i=1;i<=n;i++)
                cout<<s[n-1];
                cout<<endl;
        }
    }

    B:http://codeforces.com/contest/1400/problem/B

    题意:

    两个袋子大小:p,f

    两种物品数量:c1,c2

    两种物品所占空间:s,w

    求能装的最大数量

    解析:

    贪心来讲,规定s<w,那么对于第一个袋子,尽量先放s,然后w,第二个袋子也是如此

    根据这个贪心思路,可以对第一个袋子拿取的s数量进行枚举,s装好,再装w。c1,c2去掉之前的消耗,再对第二个袋子进行同样操作。

    细节在注释里

    #include<bits/stdc++.h>
    #include<map>
    #include<iostream>
    #include<cstring>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    const int maxn=1e5+10;
    const int maxn2=1e9+10;
    struct node
    {
        int x1,y1,x2,y2;
    }st[maxn];
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {
            ll p,f;
            ll c1,c2,s,w;
            cin>>p>>f>>c1>>c2>>s>>w;
            ll maxx=0;  //这里并没有交换s,w,第一个袋子虽然应该优先装小的,但是下面的for已经枚举到了第一种袋子的所有可能
            for(int i=0;i<=min(c1,p/s);i++)
            {
                ll s1,s2,s3;//i,s1为第一个袋子分别装s,w的数量。s2,s3分别为第二个袋子装s,w的数量
                s1=(p-s*i);
                s1=min(s1/w,c2);
                if(s<=w)  //第二个袋子优先选小
                {
                    if(f>=(c1-i)*s)  //还能再装s
                    {
                        s2=c1-i;
                        s3=min(c2-s1,(f-(c1-i)*s)/w);  
                    }    
                    else
                    {
                        s2=f/s; 
                        s3=0;
                    }
                }    
                else
                {
                    if(f>=(c2-s1)*w)//还能再装w
                    {
                        s2=c2-s1;
                        s3=min(c1-i,(f-(c2-s1)*w)/s);
                    }    
                    else
                    {
                        s2=0;
                        s3=f/w;
                    }                
                }
                maxx=max(maxx,i+s1+s2+s3);
            } 
            cout<<maxx<<endl;
        }
    }

    C:http://codeforces.com/contest/1400/problem/C

    题意:

    给出字符串s和整数x,求字符串w

    s满足:

    w[i+x]或w[i-x]为1,si为1,否则si为0

    解析:

    初始化w全为1。

    遍历si的'0',把w[i]变成符合对应要求

    再次遍历si的'1',如果w[i+x]==0&&w[i-x]==0,输出-1

    #include<bits/stdc++.h>
    #include<map>
    #include<iostream>
    #include<cstring>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    const int maxn=1e5+10;
    const int maxn2=1e9+10;
    char s1[maxn],s2[maxn];
    struct node
    {
        int x1,y1,x2,y2;
    }st[maxn];
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {
            int x;
            cin>>s1>>x;
            int le=strlen(s1);
            for(int i=0;i<le;i++)
                s2[i]='1';
            for(int i=0;i<le;i++)
            {
                if(s1[i]=='0')
                {
                    if(i>=x)
                        s2[i-x]='0';
                    if(i+x<le)
                        s2[i+x]='0';
                }
            }
            int ok = 0;
            for(int i=0;i<le;i++)
            {
                int ok1=0,ok2=0;
                if(s1[i]=='1')
                {
                    if(i>=x&&s2[i-x]=='1')
                        ok1=1;
                    if(i+x<le&&s2[i+x]=='1')
                        ok2=1;
                    if(!ok1&&!ok2)
                    {
                        ok=1;break;
                    }
                }
            }
            if(ok)
                cout<<"-1"<<endl;
            else
                {
                    for(int i=0;i<le;i++)
                        cout<<s2[i];
                        cout<<endl;
                }
        }
    }

    D:http://codeforces.com/contest/1400/problem/D

    题意:

    数组ai,1<=i<j<k<l<=n,求ai=ak,aj=al的数量

    解析:

    枚举j,l。

    假设aj==al

    ....aj....ax.....al,要想凑够满足题意的那四个,需要aj之前存在与ax相等的数,有几个,就能和aj,al凑成几个。所以就需要记录aj之前出现了几个ax

    cnt[]记录aj之前的各个数字出现的次数。

    要注意一下顺序问题,cnt[]是要在for的最后更新才行。

    #include<bits/stdc++.h>
    #include<map>
    #include<iostream>
    #include<cstring>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    const int maxn=3e3+10;
    const int maxn2=1e9+10;
    char s1[maxn],s2[maxn];
    int a[maxn];
    ll cnt[maxn];
    struct node
    {
        int x1,y1,x2,y2;
    }st[maxn];
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {
            memset(cnt,0,sizeof(cnt));
            int n;
            cin>>n;
            for(int i=1;i<=n;i++)
                cin>>a[i];
            ll sum = 0 ;
            for(int j=1;j<n;j++)
            {
                int md=0;
                for(int l=j+1;l<=n;l++)
                {
                    if(a[j]==a[l])
                        sum+=md;
                    md+=cnt[a[l]];
                }
                cnt[a[j]]++;
            }
            cout<<sum<<endl;
        }
    }

    E:http://codeforces.com/contest/1400/problem/E

    题意:

    给出数组

    操作1:[L,R]集体减1

    操作2:对任意一个数,把它变成比它自己小的任意一个数

    把所有数归0的最小操作数

    解析:

    分治

    之前做过。

    [L,R]都变0的话,需要r-l+1步,

    与集体减1那个操作取个min就可以了

    #include<bits/stdc++.h>
    #include<map>
    #include<iostream>
    #include<cstring>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    const int maxn=5e3+10;
    const int maxn2=1e9+10;
    const int mod=1e9+10;
    char s1[maxn],s2[maxn];
    ll a[maxn];
    ll cnt[maxn];
    struct node
    {
        int x1,y1,x2,y2;
    }st[maxn];
    int ac(int l,int r)
    {
        if(l>r)    return 0;
        int minn=mod;
        int k;
        for(int i=l;i<=r;i++)
        {
            if(a[i]<minn)
            {
                minn=a[i];
                k=i;
            }
        }
        int md=a[k];
        for(int i=l;i<=r;i++)
            a[i]-=minn;
        return min(r-l+1,md+ac(l,k-1)+ac(k+1,r));
    }
    int sum=0;
    int main()
    {
        int n;
        cin>>n;
        for(int i=1;i<=n;i++)
            cin>>a[i];
        cout<<ac(1,n)<<endl;
    //    cout<<sum<<endl;
    }
  • 相关阅读:
    StackExchange.Redis 文档翻译
    性能分析
    脚本
    KEYS,SCAN,FLUSHDB 等等,这些命令在哪里?
    事件
    发布/订阅 消息顺序
    Redis中的事务
    键、值以及通道
    管道和多路复用器
    配置
  • 原文地址:https://www.cnblogs.com/liyexin/p/13572992.html
Copyright © 2011-2022 走看看