ACM/ICPC 2018亚洲区预选赛北京赛站网络赛 B. Tomb Raider(二进制枚举)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sugarbliss/article/details/82919592

传送门

题意:给n个字符串,首尾相连,求最长公共子序列,若答案多个,输出字典序最小的

思路:暴力把每个字符串的每个子序列放入map(要记得不能重复),出现n次的就是公共的子序列,符合条件的公共子序列都放入vector,最后排序,得到最长的字典序最小的那个 就是答案

#include <bits/stdc++.h>
using namespace std;
map<string, int> mp,vis;
vector <string> v;
string s, str, ch;
bool cmp(string a, string b)
{
    if(a.length() == b.length()) return a < b;
    return a.length() > b.length();
}
void solve(int x)
{
    string st = ch.substr(x);
    st += ch.substr(0,x);
    str = st;
}
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        int m = n;
        int flag = 0;
        v.clear(); mp.clear();
        while(m--)
        {
            cin >> ch;
            int len = ch.length();
            for(int k = 0; k < len; k++)
            {
                solve(k);
                for(int i = 1; i < (1<<len); i++)
                {
                    for(int j = 0; j < len; j++)
                    {
                        if(i & (1 << j))
                            s += str[j];
                    }
                    if(vis[s] == 0)
                    {
                        mp[s]++;
                        vis[s] = 1;
                    }
                    s.clear();
                }
            }
            vis.clear();
        }
        for(auto it : mp)
        {
            if(it.second == n)
            {
                v.push_back(it.first);
                flag = 1;
            }

        }
        sort(v.begin(), v.end(), cmp);
        if(flag) cout << v[0] <<endl;
        else puts("0");
    }
}

猜你喜欢

转载自blog.csdn.net/sugarbliss/article/details/82919592