hdu--5510

来源:互联网 发布:淘宝网违规提醒 编辑:程序博客网 时间:2024/05/16 18:16

Bazinga

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1472    Accepted Submission(s): 459


Problem Description
Ladies and gentlemen, please sit up straight.
Don't tilt your head. I'm serious.

For n given strings S1,S2,,Sn, labelled from 1 to n, you should find the largest i (1in) such that there exists an integer j (1j<i) and Sj is not a substring of Si.

A substring of a string Si is another string that occurs in Si. For example, ``ruiz" is a substring of ``ruizhang", and ``rzhang" is not a substring of ``ruizhang".
 

Input
The first line contains an integer t (1t50) which is the number of test cases.
For each test case, the first line is the positive integer n (1n500) and in the following n lines list are the strings S1,S2,,Sn.
All strings are given in lower-case letters and strings are no longer than 2000 letters.
 

Output
For each test case, output the largest label you get. If it does not exist, output 1.
 

Sample Input
45ababczabcabcdzabcd4youlovinyouaboutlovinyouallaboutlovinyou5dedefabcdabcdeabcdef3abaccc
 

Sample Output
Case #1: 4Case #2: -1Case #3: 4Case #4: 3
解题思路:在写这题时需要用到匹配算法,一般想到节省时间的就是用kmp,但在c++中提供了一个函数strstr(str1,str2) 函数用于判断字符串str2是否是str1的子串。如果是,则该函数返回str2在str1中首次出现的地址;否则,返回NULL。所以用这个函数更为方便。这题需要剪枝否则会超时。剪枝:首先对每对相邻的子串进行判断,如果编号小的字符串是编号大的字符串的子串,那么该编号小的字符串在后续的判断中无需出现了。接着就从最后一个字符串开始扫描判断就OK了。
#include<stdio.h>#include<string.h>char s[510][2005];int num[510];int main(){int t,n,i,j,k;k=1;scanf("%d",&t);while(t--){scanf("%d",&n);for(i=1;i<=n;i++){scanf("%s",s[i]);}//输入 int v=-1;memset(num,0,sizeof(num));for(i=1;i<n;i++){if(strstr(s[i+1],s[i])!=NULL){num[i]=1;}}//剪枝       for(i=n;i>=2;i--){      for(j=i-1;j>=1;j--){      if(num[j])continue;      int l1=strlen(s[i]);      int l2=strlen(s[j]);      if(l1<l2)continue;      if(strstr(s[i],s[j])==NULL){      v=i;      break;      }      }      if(v!=-1)break;      }      printf("Case #%d: %d\n",k++,v);    }return 0;}


 


0 0
原创粉丝点击