zoukankan      html  css  js  c++  java
  • Educational Codeforces round 78 A、B

    链接:https://codeforces.com/contest/1278


    A:Shuffle Hashing


    题意:对于一个字符串p可以执行一个”hash”操作,首先将p内的元素随机排列(可能保持原样),随后在p的前面和后面分别加两个字符串(可以为空),组成的新字符串称为h。输入字符串p和h,输出h是否可能是p经过hash操作而来。

        例如:输入p = “abacaba”,h = “zyxaabcaabkjh”,输出YES

    分析:hash操作分为两步:①随机排列p中的元素②在p的前面和后面分别加两个字符串组成一个新的字符串。那么首先,进行第一步操作之后的p如果记作p’,显然有p中各元素出现的次数与p’中的相等。因此检测另一个字符串是否是p随机排列而来可以使用一个计数数组检测其中各元素出现的次数。其次,②说明p’在h中是连续的一串子字符串,记p长度为plen,h为hlen,则其长度是plen,由此,我们可以遍历h从0位开始一直到hlen-plen位开始的长度为plen的子字符串是否是p随机排列而来。

    代码:

    #include <iostream>
    #include <string>
    #include <cstring>
    using namespace std;
    
    int cnt[30];
    int main()
    {
        int T;cin >> T;
        while(T--)
        {
            string p,h;cin >> p >> h;
            int plen = p.length(),hlen = h.length();
            int ok = -1;
            for(int i = 0;i <= hlen - plen;++i)
            {
                memset(cnt,0,sizeof(cnt));
                string tmp = h.substr(i,plen);
                for(int j = 0;j < plen;++j)
                {
                    ++cnt[tmp[j] - 'a'];
                    --cnt[p[j] - 'a'];
                }
                ok = 1;
                for(int i = 0;i < 30;++i)
                {
                    if(cnt[i] != 0)
                    {
                        ok = 0;
                        break;
                    }
                }
                if(ok == 1)
                    break;
            }
            if(ok == 1)
                cout << "YES
    ";
            else
                cout << "NO
    ";
        }
        return 0;
    }

    B:A and B


    题意:给定两个变量a,b。每次选择两者之间的一个数,执行一个操作:将这个数加上i(i = 当前执行的第i步),求至少多少步可以使a和b相等。

    分析:在进行了n次操作之后,对于a和b两个数来说,总体上增加的是dsum = n(n+1)/2。但是如果想要把总体增加的和运用到a和b两个数单个身上来说的话就会变得很复杂,因为你没法知道第几步是给a增加的还是b增加的。所以,我们可以从整体上来看,对于a和b而言,他们的和本来是cursum = a+b,进行了n次操作之后会变成cursum + dsum = a’ + b’(此时a‘ == b’),那么就可以从中得到一个重要信息:cursum+dsum由于这个时候a’ == b’,那么cursum + dsum一定是2的倍数,否则不成立,其次,(cursum+dsum)/2也一定>=max(a,b),因为极端的情况就是一边很小,一直在很小的一边加,最后与右边更大的值相等,倘若(cursum + dsum)/2不满足>=max(a,b),则说明虽然此时加的数已经是2的倍数,但是还不足以分成两半使得a和b此时相等。

    代码:

    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    int main()
    {
        int T;cin >> T;
        while(T--)
        {
            int a,b;cin >> a >> b;
            if(a == b)
            {
                cout << 0 << endl;
                continue;
            }
            int cursum = a + b,n = 1,nsum = 0;
            for(;n <= max(a,b)*2;++n)
            {
                nsum += n;
                if(((cursum + nsum) & 1 ) == 0 && ((cursum + nsum) / 2) >= max(a,b))
                {
                    cout << n << endl;
                    break;
                }
            }
        }
    }



  • 相关阅读:
    Helpers Overview
    Validation
    Support Facades
    Session Store
    位运算(参考百科)
    开源项目_可能使用到的开源项目集合
    秒杀系统架构分析与实战(转)
    shell命令之根据字符串查询文件对应行记录
    MySQL做为手动开启事务用法
    spring 加载bean过程源码简易解剖(转载)
  • 原文地址:https://www.cnblogs.com/HotPants/p/12074778.html
Copyright © 2011-2022 走看看