题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2328
Beside other services, ACM helps companies to clearly state their “corporate identity”, which includes company logo but also other signs, like trademarks. One of such companies is Internet Building Masters (IBM), which has recently asked ACM for a help with their new identity. IBM do not want to change their existing logos and trademarks completely, because their customers are used to the old ones. Therefore, ACM will only change existing trademarks instead of creating new ones.
After several other proposals, it was decided to take all existing trademarks and find the longest common sequence of letters that is contained in all of them. This sequence will be graphically emphasized to form a new logo. Then, the old trademarks may still be used while showing the new identity.
Your task is to find such a sequence.
Input
The input contains several tasks. Each task begins with a line containing a positive integer N, the number of trademarks (2 ≤ N ≤ 4000). The number is followed by N lines, each containing one trademark. Trademarks will be composed only from lowercase letters, the length of each trademark will be at least 1 and at most 200 characters.
After the last trademark, the next task begins. The last task is followed by a line containing zero.
Output
For each task, output a single line containing the longest string contained as a substring in all trademarks. If there are several strings of the same length, print the one that is lexicographically smallest. If there is no such non-empty string, output the words “IDENTITY LOST” instead.
Sample Input
3 aabbaabb abbababb bbbbbabb 2 xyz abc 0
Sample Output
abb IDENTITY LOST
题目翻译:
除了其他服务外,ACM 还帮助公司明确说明其"公司身份",其中包括公司徽标,但也包括其他标志(如商标)。其中一家是互联网建筑大师(IBM),它最近向ACM寻求帮助,帮助他们的新身份。IBM 不希望完全更改其现有徽标和商标,因为他们的客户已经习惯了旧徽标和商标。因此,ACM 只会更改现有商标,而不是创建新商标。
在提出其他几个建议后,决定采用所有现有的商标,并找到所有商标中包含的最长通用字母
序列。此序列将以图形方式强调,以形成一个新的徽标。然后,在显示新标识时,仍可以使用旧商标。
你的任务是找到这样一个
序列。
输入
输入包含多个任务。每个任务都以一行包含正整数 N 的行开始,该整数为商标数(2 = N = 4000)。该数字后跟 N 行,每行包含一个商标。商标仅由小写字母组成,每个商标的长度至少为 1 和最多 200 个字符。
在最后一个商标之后,下一个任务
开始。最后一个任务后跟一行,包含零。
输出
对于每个任务,输出包含所有商标中作为子字符串包含的最长字符串的一行。如果有多个长度相同的字符串,则打印字典最小字符串。如果没有此类非空字符串,请改为输出单词"标识 LOST"。
输出所有字符串的最长子串,和上个题差不多。
可以用扩展kmp去做也可以直接暴力
#include <iostream>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn=4e3+5;
int nxt[maxn];
string s[maxn];
vector<string> ss;
class cmp{
public:
bool operator () (const string a,const string b) const{
return a.size()==b.size()?a>b:a.size()<b.size();
}
};
void getnext(string a){
int len=a.size();
int j=0,k=-1;
nxt[0]=-1;
while(j<len){
if(k==-1||a[j]==a[k])
nxt[++j]=++k;
else k=nxt[k];
}
}
bool kmp(int id,string b){
getnext(b);
int i=0,j=0;
int len=s[id].size();
while(i<len){
if(j==-1||s[id][i]==b[j]) j++,i++;
else j=nxt[j];
if(j==b.size()) return true;
}
return false;
}
int main(int argc, char** argv) {
ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int n;
while(cin>>n&&n){
for(int i = 0;i<n;++i) cin>>s[i];
string str=s[0];
int len=str.size();
int ans=1;
for(int i=len;i>0;--i){
int flag=1;
ss.clear();
for(int j=0;i+j<=len;j++){
flag=1;
string s1=str.substr(j,i);
for(int k = 1;k<n;++k){
if(!kmp(k,s1)){
flag=0;
break;
}
}
if(flag){
ans=0;
ss.push_back(s1);
}
}
if(flag||!ss.empty()){
cout<<*max_element(ss.begin(),ss.end(),cmp())<<endl;
break;
}
}
if(ans) cout<<"IDENTITY LOST"<<endl;
}
return 0;
}