zoukankan      html  css  js  c++  java
  • 1.29 educational round 81

    1.29 Educational Codeforces Round 81

    A Display The Number

    题目描述

    数字屏上0-9数字点亮分别需要不同的段、给定一定段,问能够点亮的最大的数字是几

    题解

    对于偶数段 ,则最大数字的每一位都是1就可以,对于奇数段,令第一位数字是7,之后全都是1即可

    B Infinite Prefixes

    题目描述

    有一个长度为n的01串,可以无限次叠加,定义一个前缀01差:前(i)项中0比1多的个数,问有多少个前缀01差等于(m)

    题解

    每一个串存在一个(u),即整串的前缀01差,无限前缀能组成的数字仅有前(n)项前缀01差及无限u的叠加

    (注意考虑特殊条件) 不考虑就hack

    C Obtain The String

    题目描述

    有两个小写字母字符串(s)(t),定义操作:每次可将s的一个非连续子串取出,求最小的操作数(n),可使得(n)次得到的子串连续成为字符串(t)

    题解

    直接贪心,利用子序列自动机加速

    将26个字母保存1个(nex)二维数组,(nex_{ij})表示第(s)在第(i)个位置后的字母$j $第一次出现的位置,我们在求解过程中:

    首先查找t的第一个字母在s中第一次出现的位置,即(nex_{0,t_1}),找到第一个字母后,寻找t的第二个字母的过程就是在(s)(t)的第一个字母的位置后继续寻找第一次出现第二个字母的位置,以此类推,若是找不到,则操作数++,重新寻找

    #include<bits/stdc++.h>
    using namespace std;
    int T;
    char s[100005],t[100005];
    int nxt[100005][26];
    int main()
    {
        scanf("%d",&T);
        while(T--)
        {
            scanf("%s",s+1);
            scanf("%s",t+1);
            int n=strlen(s+1),m=strlen(t+1);
            for(int j=0;j<26;++j)nxt[n][j]=0;
            for(int i=n-1;i>=0;--i)
            {
                for(int j=0;j<26;++j)nxt[i][j]=nxt[i+1][j];
                nxt[i][s[i+1]-'a']=i+1;
            }
            int now=0,ans=1;
            for(int i=1;i<=m;++i)
            {
                now=nxt[now][t[i]-'a'];
                if(!now)
                {
                    ans++;
                    now=nxt[now][t[i]-'a'];
                    if(!now){ans=-1;break;}
                }
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    

    D Same GCDs

    题目描述

    给定(a,m),计算$sumlimits_{i = 0}^{m - 1} {[gcd (a,m) = = gcd (a + i,m)]} $

    题解

    (gcd (a,m) = d o gcd (frac{a}{d},frac{m}{d}) = 1)

    则原式可化为

    [{egin{array}{l}sumlimits_{i = 0}^{m - 1} {[gcd (a + i,m){ m{ = = }}d]} \ = sumlimits_{i = 0}^{m - 1} {[gcd (frac{{a + i}}{d},frac{m}{d}){ m{ = = }}1]} = sumlimits_{i = a}^{m - 1} {[gcd (frac{i}{d},frac{m}{d})]} + sumlimits_{i = m{ m{ + 1}}}^{m + a} {[gcd (frac{i}{d},frac{m}{d})]} = sumlimits_{i = { m{1}}}^m {[gcd (frac{i}{d},frac{m}{d})]} = varphi (frac{m}{d})end{array}} ]

    直接求欧拉函数即可

    E Permutation Separation

    题目描述

    给一个排列,每个排列中的第(i)个数字为(p_i),权值为(w_i).你可以选择一个位置切一刀把它分成左右两部分,然后你可以花费(w_i)(p_i)移动到另一个部分。最终要保证左半部分的最大值小于右半部分的最小值。

    题解

    基础还是太弱,看了半天题解感觉终于明白了

    首先暴力解法:就是枚举将左右集合分开的位置,然后枚举边界x,使得左边集合大于x的数与右边集合小于x的数花费和最小

    线段树解法:

    线段树是将枚举的边界x作为叶子节点的

    如果能够确定切的位置 左边集合与右边集合均已经确定,每一个叶子节点x保存的是当前集合下以x为边界所需花费,由于线段树维护的是最小值,全局最小值就是当前确定集合的最小花费。

    如何更新:

    当集合发生改变时,比如说左边集合中新增了右边集合的(y),权值为(w),则当前集合下的最优解法中的以比y小的边界均需要将y移动到右边,区间增加(w),比y大的边界则会略去这一步骤,即区间减去(w)

    F Good Contest

    略。。。。。 菜的一批做不来
  • 相关阅读:
    【Kubernetes】Service 实现探索
    【Kubernetes】浏览器访问服务
    【Kubernetes】访问入口-Service
    oracle 分页查询
    本地cmd命令打war包、解压war包
    xp系统上安装和使用kettle
    VWware15安装windows XP纯净版虚拟机
    JDK8:HashMap源码解析:TreeNode类的balanceInsertion方法
    红黑树
    kettle JVM内存设置-
  • 原文地址:https://www.cnblogs.com/lhsghhqgmzy/p/12256726.html
Copyright © 2011-2022 走看看