• codeforces 889B


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

    题意:给你 n 个由小写字母组成的字符串,n个字符串全不相同,要求构造一个母串,使所有字符串在母串中出现的频率都是最大。如果母串有多种情况,输出长度最短的且字典序最小的;若没有这个母串,输出 NO;

    题解:很容易可以看出每个字符最多只能出现一次,要是某个字符串中某个单词出现多次,肯定输出 no;

         那么考虑下答案的最长个数,每个小写字母出现一次,最长为26个字母,它的子串的最大数目为(1+26)* 26 / 2 = 351;

         那么只要 n 大于351 直接 no;接下来 n 只有 351 要怎么暴力就怎么暴力了。

            (写着写着突然想到,好像自己写烦了,若一个字符串中某个字符有后继,那么这个字符的后继就是唯一的,遍历每个字符串,若字符的后继有冲突,则 no)

      

    下面是写烦的代码:

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<string>
    #include<cstring>
    #include<set>
    using namespace std;
    string str[400];
    int isv[400];
    set<string> se;
    bool isok(string s1)
    {
        if( s1.size() > 26 ) return false;
        set<char>ch; 
        for(int i = 0; i < s1.size(); ++i) ch.insert(s1[i]);
        if(s1.size()!=ch.size()) return false;
        return true;
    }
    int solve(string s1, string s2)
    {
        if( s1.find(s2) != std::string::npos) return 1;
        if( s2.find(s1) != std::string::npos) return 2;
        set<char>ch; 
        for(int i = 0; i < s1.size(); ++i) ch.insert(s1[i]);
        for(int i = 0; i < s2.size(); ++i) ch.insert(s2[i]);
        int len = s1.size() + s2.size() - ch.size();
        if(!len) return 3;
        int i1, i2; string sss;
        i1 = s1.size()-len; i2 = 0; sss = s1.substr(0, s1.size()-len);
        while(i1 < s1.size() && s1[i1]==s2[i2]) ++i1, ++i2;
        if(i1==s1.size()) 
        {
            se.insert(sss+s2);
            return 4;
        }
        i1 = 0; i2 = s2.size()-len; sss = s2.substr(0, s2.size()-len);
        while(i2 < s2.size() && s1[i1]==s2[i2]) ++i1, ++i2;
        if(i2==s2.size())
        {
            se.insert(sss+s1);
            return 4;
        }
        return 5;
    }
    int main (void)
    {
        ios::sync_with_stdio(false);
        int n; cin >> n;
        if(n > 27*13)
        {
            cout<<"NO";
            return 0;
        }
        for(int i = 1; i <= n; ++i)
        {
            cin >> str[i];
            if( !isok(str[i]) )
            {
                cout<<"NO";
                return 0;
            }
        }
        int top = n;
        while(true)
        {
            memset(isv, 0x00, sizeof(isv));
            for(int i = 1; i <= top; ++i)
            {
                if(isv[i]) continue;
                for(int j = i+1; j <= top; ++j)
                {
                    if(isv[j]) continue;
                    int c = solve(str[i], str[j]);
                    if(c==1) isv[j] = 1;
                    else if(c==2) isv[i] = 1;
                    else if(c==4) isv[i] = isv[j] = 1;
                    else if(c==5)
                    {
                        cout<<"NO";
                        return 0;
                    }
                    if(isv[i]==1) break;
                }
            }
            if(se.empty()) break;
            int to = 0;
            for(int i = 1; i <= top; ++i)
            {
                if(!isv[i]) str[++to] = str[i];
            }
            set<string>::iterator it;
            for(it = se.begin(); it!=se.end(); ++it) str[++to] = *it;
            se.clear();
            top = to;
        }
        for(int i = 1; i <= top; ++i)
        {
            if(!isv[i]) se.insert( str[i] );
        }
        set<string>::iterator it;
        for(it = se.begin(); it!=se.end(); ++it) cout << (*it);
    } 
  • 相关阅读:
    ThinkPad R400 windows 2008 下网卡、蓝牙驱动程序安装过程记录
    google 小百货工具
    今天发现数据库到处都有,还是学习一种比较好
    今天玩玩Android == 了解一下
    p 同学推荐的 书 读完了 == 感慨颇深,霍霍
    new confirm and new idea == need time
    娑罗双树,半枯半荣,娑罗花开,盛者必衰
    使用VC6.0 连接PostgreSQL数据库
    vc6操作PostgreSQL 测试下异步通知接口
    准备这几天看的内容
  • 原文地址:https://www.cnblogs.com/lkcc/p/7846803.html
Copyright © 2020-2023  润新知