1084: 最长公共子序列Ⅱ(用二进制表示来取整个字符串的子串)

题目描述

PIPI又来刁难胖虎了~
现在PIPI有n个字符串项链,它要你求出这n个环的最长公共子序列,并输出~
PS:注意每个字符串都成环了,首尾相连~

输入

多组数据
第一行为一个整数n,1<=n<=10
接下来n行,每行一个字符串,保证字符串长度不超过8.

输出

输出一个字符串,代表n个串的最长公共子序列。若不存在,输出0.若有多个答案,输出字典序最小的。

样例输入

2
abcdefg
zaxcdkgb
5
abcdef
kedajceu
adbac
abcdef
abcdafc
2
abc
def

样例输出

acdg
acd
0

#include<bits/stdc++.h>
using namespace std;
int n;
string s,ans;
unordered_map<string,bool>legal,tmp; ///legal保存合法序列 tmp保存合法子序列
unordered_map<string,bool>::iterator it;
main()
{
    while(scanf("%d",&n)!=EOF)
    {
        for(int i=0;i<n;i++)
        {
            tmp.clear();
            ans.clear();
            string box;
            cin>>s;
            int len=s.size(),tp=1<<len;
            s+=s;
            for(int l=0;l<len;l++)
            {
                for(int j=0;j<tp;j++)
                {
                    for(int k=0;k<len;k++)
                    {
                       if(j&(1<<k)) box.push_back(s[l+k]);
                    }
                    if(i==0||legal.count(box)) tmp[box]=1;///tmp保存该字符串中的合法且属于整个字符串集合中的子串
                    box.clear();
                }
            }
            if(i==n-1)
            {
                for(it=tmp.begin();it!=tmp.end();it++)
                    if(ans.size()<it->first.size()) ans=it->first;
                    else if(ans.size()==it->first.size()&&ans>it->first) ans=it->first;///ans保存最长的子序列
            }
            else
            {
                legal.clear();
                for(it=tmp.begin();it!=tmp.end();it++) legal[it->first]=1; ///一层层叠加最后输出的子串一定是整个字符串序列中的子序列
            }
        }
        if(!ans.size()) printf("0\n");
        else    cout<<ans<<endl;
    }
}

发布了78 篇原创文章 · 获赞 7 · 访问量 4583

猜你喜欢

转载自blog.csdn.net/weixin_44433678/article/details/104242877