The Dominator of Strings

Time Limit: 3000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 515    Accepted Submission(s): 146


Problem Description
Here you have a set of strings. A dominator is a string of the set dominating all strings else. The string S is dominated by T if S is a substring of T .
 
Input
The input contains several test cases and the first line provides the total number of cases.
For each test case, the first line contains an integer N indicating the size of the set.
Each of the following N lines describes a string of the set in lowercase.
The total length of strings in each case has the limit of 100000 .
The limit is 30MB for the input file.
Output
For each test case, output a dominator if exist, or No if not.
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
Source

唉 ,,,,好坑啊,开始用ac自动机,要不超内存,要不就超时,挑了将近两三个小时,没ac,比赛结束,听说用kmp就能过,然后试了下,AC


代码如下:

#include <iostream>  
#include <cstdio>  
#include <stdlib.h>
#include <cstring>  
#include <queue>  
using namespace std;
int kmp_find(const char* target,const char* pattern)
{
    const int target_length = strlen(target);
    const int pattern_length = strlen(pattern);
    int * overlay_value = new int[pattern_length];
    overlay_value[0] = -1;//存前缀和后缀相同元素的长度
    int index = 0;
    for(int i=1;i<pattern_length;++i)
    {
        index = overlay_value[i-1];
        while(index>=0 && pattern[index+1]!=pattern[i])
        {
            index  = overlay_value[index];
        }
        if(pattern[index+1]==pattern[i])
        {
            overlay_value[i] = index +1;
        }
        else
        {
            overlay_value[i] = -1;
        }
    }

    //match algorithm start
    int pattern_index = 0;
    int target_index = 0;
    while(pattern_index<pattern_length&&target_index<target_length)
    {
        if(target[target_index]==pattern[pattern_index])
        {
            ++target_index;
            ++pattern_index;
        }
        else if(pattern_index==0)
        {
            ++target_index;
        }
        else
        {
            pattern_index = overlay_value[pattern_index-1]+1;
        }
    }
    delete [] overlay_value;
    if(pattern_index==pattern_length)
    {
        return target_index-pattern_index;
    }
    else
    {
        return -1;
    }
   
}  
char s[200002];
char* p[100005];
int main()  
{  
    int t,n,m,len,i; 
    scanf("%d",&t);  
    while(t--)  
    {  
    	scanf("%d",&n);
    	memset(s,'\0',sizeof(s));
    	len=m=0;
    	p[0]=s;
    	for(int i=0;i<n;i++)
    	{
    		scanf("%s",p[i]);
    		if(strlen(p[i])>len)
		{
			len=strlen(p[i]);
			m=i;
		} 
    		p[i+1]=p[i]+strlen(p[i])+1; 
	}
        int ans=0;
	for(int i=0;i<n;i++)
	{
		if(i!=m&&kmp_find(p[m],p[i])!=-1)
			ans++;
	}
	if(ans==n-1)
		printf("%s\n",p[m]);
	else
		printf("No\n");
    }  
    return 0;  
}  








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值