【ACM-ICPC 2018 北京赛区网络预赛】B题Tomb Raider ---- 状态压缩+思维★

版权声明:本文为博主原创文章,转载请预先通知博主(〃'▽'〃)。 https://blog.csdn.net/m0_37624640/article/details/82817071

题目传送门

题意:

  • 找出这n个串的最长公共子序列,我们把每个串都看成环,子序列可以从环中找出。
  • 其中要保证公共子序列的字典序最小。
  • 比如:
  • abcdef
    kedajceu
  • 其中他们的公共子序列是 acd 

做法:

  • 每个串的长度最多不超过8,最多10组数据,显然我们可以通过状态压缩枚举子集找到所有的子串。
  • 由于每个串是环状的,所以我们把串加倍,模拟成环,枚举第一个串s1所有长度为len(s1)的子串去暴力判断其他串即可。
#include<bits/stdc++.h>
#define IO          ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define pb(x)       push_back(x)
#define sz(x)       (int)(x).size()
#define sc(x)       scanf("%d",&x)
#define pr(x)       printf("%d\n",x)
#define abs(x)      ((x)<0 ? -(x) : x)
#define all(x)      x.begin(),x.end()
#define mk(x,y)     make_pair(x,y)
#define debug       printf("!!!!!!\n")
#define fin         freopen("in.txt","r",stdin)
#define fout        freopen("out.txt","w",stdout)
using namespace std;
typedef long long ll;
const int mod = 1e9+7;
const double PI = 4*atan(1.0);
const int maxm = 1e8+5;
const int maxn = 1e5+5;
const int INF = 0x3f3f3f3f;
string s[20],tmp,ans;
bool check(int x)
{
    int p1 = 0,p2 = 0;
    int st = INF;
    while(p1<(int)s[x].length() && p2<(int)tmp.length())
    {
        if(s[x][p1] == tmp[p2]){
            p1++;
            p2++;
            if(p2 == 1) st = p1-1;
        }
        else{
            if(tmp[0] == s[x][p1] && p2 == 1){
                st = p1;
            }
            p1++;
        }
    }
    return (p1-st<=(int)s[x].length()/2) && (p2 ==(int)tmp.length());
}
int main()
{
    #ifdef LOCAL_FILE
    fin;
    #endif // LOCAL_FILE
    IO;
    int n;
    while(cin>>n)
    {
        ans = "";
        for(int i=1;i<=n;i++){
            cin>>s[i];
            s[i]+=s[i];//加倍
        }
        int len = s[1].length()/2;
        for(int l=0;l<len;l++)
        {
            for(int S=1;S<(1<<len);S++)
            {
                tmp = "";
                int res = 0;
                for(int i=0;i<len;i++)
                {
                    if(S&(1<<i)) tmp+=s[1][i+l];
                }
                for(int i=2;i<=n;i++) res+=check(i);
                if(res == n-1)
                {
                    if(tmp.length()>ans.length())
                        ans = tmp;
                    else if(tmp.length() == ans.length())
                        if(ans>tmp) ans = tmp;
                }
            }
        }
        if(sz(ans) == 0) cout<<0<<endl;
        else cout<<ans<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_37624640/article/details/82817071