2018icpc北京网络赛B题题解

题意

给n个字符串,每个字符串是一个环(就是说起点任意),求n个字符串的最长公共子序列(LCS)

解题思路

比赛的时候刚看到这个题目要求n个字符串的lcs,并且没个字符串可以起点不一样,就是说字符串s都有s.length个不同的排列,求所有n个s里s.length个lcs,时限只有1s,求两个字符串的lcs有n^2的复杂度,思路肯定不是这样,而且n和s.length很小,发现可以直接暴力求每个字符串的所有子串(相当于求集合的所有子集),然后用set保存,答案就是n个set里最长的公共串。

AC代码

#include<bits/stdc++.h>
using namespace std;
string S[12];
set<string> cset[12];

void getstr(string a,int mark,int length,int k)
{
    bool allZero=true;
    int limit=1<<length;
    string s;
    for(int i=0;i<length;++i)
    {
        if(((1<<i)&mark)!=0)
        {
            allZero=false;
            s += a[i];
        }
    }
    if(s!=""||s.size()>1)
        cset[k].insert(s);
}

void subset(string a,int length,int k)
{
    if(length>31) return;
    int lowFlag=0;
    int highFlag=(1<<length)-1;
    for(int i=lowFlag;i<=highFlag;++i)
    {
        getstr(a,i,length,k);
    }
}

int main()
{
    int n = 0;
    while(cin >> n){
        for(int i=0;i<n;i++){
            cset[i].clear();
            cin >> S[i];
            int len = S[i].size();
            S[i] += S[i];
            for(int j=0;j<len;j++){
                string s(S[i].begin()+j,S[i].begin()+len+j);
                subset(s,s.size(),i);
            }
        }
        vector<string> ans;
        for(string s:cset[0]){
            bool ok = 1;
            for(int i=1;i<n;i++){
                if(cset[i].count(s)==0){
                    ok = 0;
                    break;
                }
            }
            if(ok) ans.push_back(s);
        }
        if(ans.size()==0){
            cout << "0" << endl;
            continue;
        }
        sort(ans.begin(),ans.end());
        string res;
        int len = 0;
        for(string s:ans){
            if(s.size()>len){
                len = s.size();
                res = s;
            }
        }
        cout << res << endl;
    }
    return 0;
}

原文地址:https://www.cnblogs.com/django-lf/p/9717437.html

时间: 2024-10-12 06:17:33

2018icpc北京网络赛B题题解的相关文章

2015北京网络赛A题The Cats&#39; Feeding Spots

题意:给你一百个点,找个以这些点为中心的最小的圆,使得这个圆恰好包含了n个点,而且这个圆的边界上并没有点 解题思路:暴力枚举每个点,求出每个点到其他点的距离,取第n大的点,判断一下. 1 #include<cstdio> 2 #include<cmath> 3 #include<algorithm> 4 #include<iostream> 5 #include<memory.h> 6 using namespace std; 7 const i

(中等) Hiho 1232 Couple Trees(15年北京网络赛F题),主席树+树链剖分。

"Couple Trees" are two trees, a husband tree and a wife tree. They are named because they look like a couple leaning on each other. They share a same root, and their branches are intertwined. In China, many lovers go to the couple trees. Under t

HDU 5033 Building(北京网络赛B题) 单调栈 找规律

做了三天,,,终于a了... 11724203 2014-09-25 09:37:44 Accepted 5033 781MS 7400K 4751 B G++ czy Building Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 1257    Accepted Submission(s): 358 Special Judg

hihoCoder #1388 : Periodic Signal ( 2016 acm 北京网络赛 F题)

时间限制:5000ms 单点时限:5000ms 内存限制:256MB 描述 Profess X is an expert in signal processing. He has a device which can send a particular 1 second signal repeatedly. The signal is A0 ... An-1 under n Hz sampling. One day, the device fell on the ground accidenta

hihocoder 1236(2015北京网络赛 J题) 分块bitset乱搞题

题目大意: 每个人有五门课成绩,初始给定一部分学生的成绩,然后每次询问给出一个学生的成绩,希望知道在给定的一堆学生的成绩比这个学生每门都低或者相等的人数 因为强行要求在线查询,所以题目要求,每次当前给定的学生成绩都异或上一次的答案 先将学生按每一门成绩都排一次序 这里将学生分块成sqrt(n)的块数,然后在当前块中用bitset容器来记录含有学生的状态 这里可以记录状态的前缀和,因为比后面成绩好的,必然比前面的学生的成绩也好 查询的时候只要查到正好比他高的学生属于哪一块,这样只要访问sqrt(n

HDU 5033 Building(北京网络赛B题)

HDU 5033 Building 题目链接 思路:利用单调栈维护建筑建的斜线,保持斜率单调性,然后可以把查询当成高度为0的建筑,和建筑和在一起考虑,从左往右和从右往左各扫一遍即可 代码: #include <cstdio> #include <cstring> #include <queue> #include <cmath> #include <algorithm> using namespace std; const int N = 200

HDU 5040 Instrusive(北京网络赛I题)

HDU 5040 Instrusive 题目链接 思路:记忆化广搜,先预处理出图,每个位置用一个二进制数表示,表示4秒为1个周期内,这个位置是否会被照到,然后进行记忆化广搜即可,状态多开一个4,表示在4秒一周期,然后进行转移即可 代码: #include <cstdio> #include <cstring> #include <queue> using namespace std; const int N = 505; const int d[4][2] = {-1,

HDU 5036 Explosion(北京网络赛E题)

HDU 5036 Explosion 题目链接 思路:对于每个点,只要考虑哪些炸掉能到他的个数cnt,那么他对应的期望就是1 / cnt,然后所以期望的和就是答案,用bitset来维护 代码: #include <cstdio> #include <cstring> #include <bitset> using namespace std; const int N = 1005; int t, n; bitset<N> bs[N]; int main()

hihocoder1236(北京网络赛J):scores 分块+bitset

北京网络赛的题- -.当时没思路,听大神们说是分块+bitset,想了一下发现确实可做,就试了一下,T了好多次终于过了 题意: 初始有n个人,每个人有五种能力值,现在有q个查询,每次查询给五个数代表查询的五种能力值,输出有多少个人每种能力值都比查询的小 n和q都是50000,每种能力值最大也为50000 思路: 对于某一个大小的能力值,有哪些人的此项能力值比他小可以用一个50000的bitset表示.这样我们在查询的时候就可以拿到5个对应的bitset,对其进行and就可以得出最终的人数 这样每