zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 86 (Rated for Div. 2) B C D题

    Educational Codeforces Round 86 (Rated for Div. 2)

    B. Binary Period

    题意

    给出一个01串t,让找到一个01串s,满足以下条件:

    1. 长度不超过2*|t|
    2. t是s的子序列
    3. s的周期尽可能的短

    思路

    如果t中全是0或者1,直接输出t。

    否则输出|t|个01

    代码

    #include<bits/stdc++.h>
    #define pb push_back
    using namespace std;
    const int N=2e5+10;
    const int mod=1e9+7;
    const int inf=0x3f3f3f3f;
    const double Pi=acos(-1.0);
    typedef unsigned long long ull;
    typedef long long ll;
    
    char str[N];
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%s",str+1);
            int len=strlen(str+1);
            int sum=0;
            for(int i=1;i<=len;i++)
                sum+=str[i]-'0';
            if(sum==0||sum==len) printf("%s
    ",str+1);
            else{
                for(int i=1;i<=len;i++)
                    printf("01");
                printf("
    ");
            }
        }
        return 0;
    }
    
    

    C. Yet Another Counting Problem

    题意

    给出两个整数a,b以及q个询问,每次询问给出区间[l,r],问在区间中有多少个数字x,
    使得(x mod a mod b!= x mod b mod a)

    思路

    因为l,r非常大,先打了个1-1000中,a=3,b=5的时候相等的x的值可能是多少。

    发现有规律。

    0 1 2 3 4
    15 16 17 18 19
    30 31 32 33 34
    45 46 47 48 49
    60 61 62 63 64
    75 76 77 78 79
    90 91 92 93 94
    105 106 107 108 109
    120 121 122 123 124
    135 136 137 138 139
    150 151 152 153 154
    165 166 167 168 169
    180 181 182 183 184
    195 196 197 198 199
    210 211 212 213 214
    225 226 227 228 229
    240 241 242 243 244
    255 256 257 258 259
    

    每段开头都是a,b的最小公倍数的倍数,长度为(max(a,b))

    代码

    #include<bits/stdc++.h>
    #define pb push_back
    using namespace std;
    const int N=2e5+10;
    const int mod=1e9+7;
    const int inf=0x3f3f3f3f;
    const double Pi=acos(-1.0);
    typedef unsigned long long ull;
    typedef long long ll;
    
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            ll a,b,q;
            scanf("%lld%lld%lld",&a,&b,&q);
            if(a>b) swap(a,b);
            ll lcm=a*b/__gcd(a,b);
            while(q--)
            {
                ll l,r;
                scanf("%lld%lld",&l,&r);
                ll lpos=l/lcm,rpos=r/lcm;
                ll lst=lpos*lcm,len=lst+b-1;
                ll rst=rpos*lcm,ren=rst+b-1;
                ll ans=0;
                if(lpos==rpos)
                {
                    ans=max((ll)0,min(r,len)-max(l,lst)+1);
                }
                else
                {
                    ans+=max((ll)0,len-l+1)+min(r,ren)-rst+1;
                    ans+=(rpos-lpos-1)*b;
                }
                printf("%lld ",r-l+1-ans);
            }
            printf("
    ");
        }
        return 0;
    }
    

    D. Multiple Testcases

    题意

    给出n个数字,最大的数字为k,然后现在要把这n个数字,分到x个数组中,每个数字中都要满足>=i的数字的数量不能超多(c_i),问x的最小值。

    思路

    直接模拟放。

    对n个数字排序,如果从前往后放不好判断题目中的限制条件,我们从后往前放。

    假如当前数字为(x),那么一个数组中大于等于它的数字最多有(c_x-1)个,我们只能放到此时数组大小小于(c_x)的数组中。

    寻找数组的过程如果遍历复杂度太高,考虑使用二分。

    我们要让数组的大小是一个有序的序列,那么每次放的时候优先放到数组中下标小的,如果没有找到合适的,

    新建一个数组。

    这样这些数组的大小是递减的。就可以使用二分查找当前数字该放到哪个数组中。

    代码

    #include<bits/stdc++.h>
    #define pb push_back
    using namespace std;
    const int N=2e5+10;
    const int mod=1e9+7;
    const int inf=0x3f3f3f3f;
    const double Pi=acos(-1.0);
    typedef unsigned long long ull;
    typedef long long ll;
    
    int arr[N],lim[N],vis[N],tmp[N];
    vector<int>vec[N];
    int main()
    {
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) scanf("%d",&arr[i]);
        for(int i=1;i<=m;i++) scanf("%d",&tmp[i]);
        sort(arr+1,arr+1+n);
        for(int i=1;i<=n;i++)
            lim[i]=tmp[arr[i]];
        int cnt=1;
        for(int i=n;i;i--)
        {
            int l=1,r=cnt-1,ans=-1;
            while(l<=r)
            {
                int mid=(l+r)/2;
                if(vec[mid].size()<lim[i])
                {
                    ans=mid;
                    r=mid-1;
                }
                else l=mid+1;
            }
            if(ans==-1)vec[cnt++].pb(arr[i]);
            else vec[ans].pb(arr[i]);
        }
        printf("%d
    ",cnt-1);
        for(int i=1;i<cnt;i++)
        {
            printf("%d ",(int)vec[i].size());
            for(int v:vec[i]) printf("%d ",v);
            printf("
    ");
        }
        return 0;
    }
    
  • 相关阅读:
    [CF1299B] Aerodynamic
    [CF1338B] Edge Weight Assignment
    [CF689C] Mike and Chocolate Thieves
    [CF729C] Road to Cinema
    [CF735C] Tennis Championship
    [CF766C] Mahmoud and a Message
    [CF797C] Minimal string
    [CF798C] Mike and gcd problem
    [CF818D] Multicolored Cars
    《剑指Offer》面试题55:字符流中第一个不重复的字符
  • 原文地址:https://www.cnblogs.com/valk3/p/13084223.html
Copyright © 2011-2022 走看看