传送门:HDU 6208
Sample Input
3 10 you better worse richer poorer sickness health death faithfulness youbemyweddedwifebetterworsericherpoorersicknesshealthtilldeathdouspartandpledgeyoumyfaithfulness 5 abc cde abcde abcde bcde 3 aaaaa aaaab aaaac
Sample Output
youbemyweddedwifebetterworsericherpoorersicknesshealthtilldeathdouspartandpledgeyoumyfaithfulness abcde No
题目大意:在给出的n个字符串中找一个字符串,要求其他的串都必须是它的子串,如果有就输出这个串,如果没有就输出No。
思路:很明显,要找的这个串一定是最长的串,如果存在多个串长度相同且最长,那么只有在这些串一毛一样的时候才符合题意。然鹅,题目给出的数据量太大了,直接开char型数组会爆内存的,所以可以选择使用string类型来存储,数组开了10W就够了。
具体做法:先找出最长的串,然后用string.find(s)函数判断其他串是不是它的子串,如果是就输出这个串,如果不是就输出No。如果find()函数返回string::npos则不是子串,如果是子串则返回匹配的第一个位置。
PS:当然这个题还有很多其他做法,比如用KMP匹配,直接套用AC自动机模板,用后缀自动机等,想具体了解的请自行百度。
PPS:自我感觉string类型的find函数和char类型的strstr函数好像都不必kmp慢很多。后者网上大神已经验证过了比kmp还快,前者没具体研究。
//Time:577MS Memory:57768K
#include<stdio.h>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;
string s[100010];
int main()
{
ios::sync_with_stdio(false);
int i,t,n,f,len,max,pos;
cin>>t;
while(t--)
{
cin>>n;
max=0;
pos=0;
for(i=0;i<n;i++)
{
cin>>s[i];
len=s[i].length();
if(len>max)
{ //找到长度最大的串,并记录它的位置
max=len;
pos=i;
}
}
f=0;
for(i=0;i<n;i++)
{ //用s.find(t)函数判断t是否是s的子串,如果不是返回 string::npos
if(s[pos].find(s[i])!=string::npos) f++;
}
//如果所有串都是最长串的子串
if(f==n) cout<<s[pos]<<endl;
else cout<<"No"<<endl;
}
return 0;
}