Bazinga

Problem Description

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

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

A substring of a string S i   is another string that occurs in S i  . 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 S 1 ,S 2 ,,S n  .
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

4
5
ab
abc
zabc
abcd
zabcd
4
you
lovinyou
aboutlovinyou
allaboutlovinyou
5
de
def
abcd
abcde
abcdef
3
a
ba
ccc

Sample Output

Case #1: 4
Case #2: -1
Case #3: 4
Case #4: 3

Source

2015ACM/ICPC亞洲區瀋陽站-重現賽(感謝東北大學) 

題意:求第i個字符串不是 1—i 個字符串(存在一個匹配不成就行),求 i 的最大值

首先定義一個vis[i][j]數組 用來存放第i個字符串與第j個字符串匹配情況,mapp[i]數組表示第i個字符串是之前字符串的子串

i從1開始  j從i-1開始匹配 ,如果第i個字符串與第j個字符串匹配成功,就更新vis數組,尋找可能不匹配的字符串在此匹配;否則,mapp[i]標記,退出當前循環。

然後從大到小判斷第i個字符串與之前的是否匹配

若i==0,則輸出-1即可,否則輸出i+1

代碼如下:

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;

const int N=500+5;
const int NMAX=2000+5;
int vis[N][N],mapp[N];
int next_s[NMAX];
char s[N][NMAX];
void get_next(int next_s[],char s[],int len)
{
    int i=0,j;
    j=next_s[0]=-1;
    while(i<len)
    {
        if(j==-1||s[i]==s[j])
        {
            i++,j++;
            next_s[i]=j;
        }
        else
            j=next_s[j];
    }
}
int kmp(char s[],char t[],int ls,int lt)
{
    int i=0,j=0;
    int ans=0;
    while(i<ls)
    {
        if(j==-1 || s[i]==t[j])
            i++,j++;
        else
            j=next_s[j];
        if(j>=lt){
            ans++;
            break;
        }
    }
    return ans;
}
int main()
{
    int t,n;
    scanf("%d",&t);
    int count=1;
    while(t--)
    {
        memset(vis,0,sizeof(vis));
        memset(mapp,1,sizeof(mapp));
        scanf("%d",&n);
        scanf("%s",s[0]);
        for(int i=1;i<n;i++)
        {
            scanf("%s",s[i]);
            int len_si=strlen(s[i]);
            for(int j=i-1;j>=0;j--)
            {
                if(j==i-1)
                {
                    memset(next_s,0,sizeof(next_s));
                    int len_sj=strlen(s[j]);
                    get_next(next_s,s[j],len_sj);
                    int ans=kmp(s[i],s[j],len_si,len_sj);
                    if(ans!=0)//匹配成功
                    {
                        for(int k=0;k<j;k++)
                            vis[i][k]=vis[i][k]|vis[j][k];
                        vis[i][j]=1;
                    }
                    else
                    {
                        mapp[i]=0;
                        break;
                    }

                }
                else
                {
                    if(!vis[i][j])
                    {
                        int len_sj=strlen(s[j]);
                        memset(next_s,0,sizeof(next_s));
                        get_next(next_s,s[j],len_sj);
                        int ans=kmp(s[i],s[j],len_si,len_sj);
                        if(ans!=0)//匹配成功
                        {
                            for(int k=0;k<j;k++)
                                vis[i][k]=vis[i][k]|vis[j][k];
                            vis[i][j]=1;
                        }
                        else
                        {
                            mapp[i]=0;
                            break;
                        }
                    }
                }
            }
        }
        int i;
        for(i=n-1;i>=1;i--)
            if(mapp[i]==0)
                break;
        if(i==0)
            printf("Case #%d: -1\n",count++);
        else
            printf("Case #%d: %d\n",count++,i+1);
    }
    return 0;
}





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章