zoukankan      html  css  js  c++  java
  • B. ZgukistringZ

    题目链接:http://codeforces.com/contest/551/problem/B

    题目大意:给你三个字符串,s1,s2,s3.  s1任意两个字符串之间可以互相交换。

    问,在s1中s2和s3在不重叠的情况下,两个字符串出现的最多次数之和的时候为多少,然后将排完序的字符串输出。

    思路:一开始打算用桶排做,将每个字符串中的字符出现的次数记录下来,然后查看每个字符串在s1中出现的次数最多为多少,然后按照最大的输出。结果交上去错了,后来才发现是求s1和s2出现的次数之和的最大值,有可能有如下情况,s1出现的最大次数为3,当s1出现次数为3时,s2的次数为1.但是,当s1出现的次数为2时,这个时候s2的次数为5,显然 3+1 < 2+5 。这个时候就应该先输出2*s1和5*s2.然后又开始改,交上去有一组样例tle了,然后过了断断续续将近两个小时才发下错在哪里,具体原因在下面的代码中解释。

    #include<bits/stdc++.h>
    using namespace std;
    # define inf 0x3f3f3f3f
    string s1,s2,s3;
    int  index;
    int d1,d2;
    int s;
    int len;
    map<char,int>q1;
    map<char,int>q2;
    map<char,int>q3;//桶排
    map<char,int >com;
    void judge()
    {
        int len=s2.size();
        d1=inf;
        for(int i=0; i<len; i++)
        {
            d1=min(d1,q1[s2[i]]/q2[s2[i]]);//这个地方要注意,和d1比较的是 (q1[s2[i]]/q2[s2[i]]),不能只是比较(d1和q1[s2[i]]),因为s2有可能是由重复字母组成的比如说 s1是‘aaa',s2是'aa',这个时候,如果按照后者的计算的话,答案是3,但是正确答案应该是1.
            //cout<<d1<<endl;
        }
        s=-1;
        int t1,t2;
        index=0;
        for(int j=0; j<=d1; j++)
        {
            t1=0,t2=0;
            t1=j;
            int d=inf;
            for(int i=0; i<26; i++)//这里就是tle的原因,一开始我是按照 s3的长度开始跑的,结果一直tle,在看别人的代码的时候,突然想了一下,如果按照最大的来算的话,s2在s1中出现的次数为十的五次方,如果s3的长度也是十的五次方,这个时候耗时就成了10的十次方了,肯定会超时。
            {
                char temp=char(i+'a');
                if(q3[temp])
                {
                    d=min(d,(q1[temp]-j*(q2[temp]))/q3[temp]);
                }
            }
            t2=d;
            if(t1+t2>s)
            {
                s=t1+t2;
                index=t1;
            }
        }
    }
    int main()
    {
        while(cin>>s1>>s2>>s3)
        {
            q1.clear();
            q2.clear();
            q3.clear();
            for(int i=0; i<26; i++)
            {
                char s=char(i+'a');
                // cout<<s<<endl;
                q1[s]=0;
                q2[s]=0;
                q3[s]=0;
            }
            for(int i=0; s1[i]; i++)q1[s1[i]]++;
            for(int i=0; s2[i]; i++)q2[s2[i]]++;
            for(int i=0; s3[i]; i++)q3[s3[i]]++;
            judge();
            for(int i=0; i<index; i++)
            {
                cout<<s2;
            }
            len=s2.size();
            for(int i=0; i<len; i++)
            {
                q1[s2[i]]-=index;
            }
            for(int i=1; i<=s-index; i++)
            {
                cout<<s3;
            }
            len=s3.size();
            int g=s-index;
            for(int i=0; i<len; i++)
            {
                q1[s3[i]]-=g;
            }
            len=s1.size();
            for(int i=0; i<len; i++)
            {
                if(q1[s1[i]])
                {
                    cout<<s1[i];
                    q1[s1[i]]--;
                }
            }
            cout<<endl;
        }
        return 0;
    }
     

  • 相关阅读:
    gulp备忘
    好文收藏
    妙味H5交互篇备忘
    [CSS3备忘] transform animation 等
    css选择器总结
    flexbox备忘
    函数
    继承2
    在 Swift 中实现单例方法
    浅谈 Swift 中的 Optionals
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10262989.html
Copyright © 2011-2022 走看看