USACO Section 2.3 Longest Prefix

Longest Prefix
IOI'96

The structure of some biological objects is represented by the sequence of their constituents, where each part is denote by an uppercase letter. Biologists are interested in decomposing a long sequence into shorter ones called primitives.

We say that a sequence S can be composed from a given set of primitives P if there is a some sequence of (possibly repeated) primitives from the set whose concatenation equals S. Not necessarily all primitives need be present. For instance the sequenceABABACABAABcan be composed from the set of primitives

	   {A, AB, BA, CA, BBC}

The first K characters of S are the prefix of S with length K. Write a program which accepts as input a set of primitives and a sequence of constituents and then computes the length of the longest prefix that can be composed from primitives.

PROGRAM NAME: prefix

INPUT FORMAT

First, the input file contains the list (length 1..200) of primitives (length 1..10) expressed as a series of space-separated strings of upper-case characters on one or more lines. The list of primitives is terminated by a line that contains nothing more than a period (`.'). No primitive appears twice in the list. Then, the input file contains a sequence S (length 1..200,000) expressed as one or more lines, none of which exceeds 76 letters in length. The "newlines" (line terminators) are not part of the string S.

SAMPLE INPUT (file prefix.in)

A AB BA CA BBC
.
ABABACABAABC

OUTPUT FORMAT

A single line containing an integer that is the length of the longest prefix that can be composed from the set P.

SAMPLE OUTPUT (file prefix.out)

11
题意:给你一系列的字符串子串,给你一个母串,求使用子串可以组成最长的母串的前缀,子串可以重复使用。
分析:直接暴力枚举 O(200000*200*10)加一些减枝。
注意:输入的母串可能有多行。
View Code
/*
  ID: dizzy_l1
  LANG: C++
  TASK: prefix
*/
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#define MAXN 200010

using namespace std;

char s[210][15],str[MAXN],tstr[100];
int lens[210];

FILE *fin  = fopen ("prefix.in", "r");
FILE *fout = fopen ("prefix.out", "w");

int main()
{
    int i,j,k,ans=0,cnt=0;
    int lenstr;
    for(cnt=0;; cnt++)
    {
        fscanf(fin,"%s",s[cnt]);
        lens[cnt]=strlen(s[cnt]);
        if(strcmp(s[cnt],".")==0) break;
    }
    while(fscanf(fin,"%s",tstr)!=EOF) strcat(str,tstr);//输入有多行
    lenstr=strlen(str);
    for(i=0; i<lenstr; i++)
    {
        for(j=0; j<cnt; j++)
        {
            if(i+lens[j]>lenstr) continue;
            for(k=0; k<lens[j]; k++)
            {
                if(str[i+k]!=s[j][k])
                {
                    break;
                }
            }
            if(k==lens[j])
            {
                ans=max(ans,i+lens[j]);
            }
        }
        if(ans<i+1) break; //母串中下标为 i 的元素不能匹配,直接跳出
    }
    fprintf(fout,"%d\n",ans);
    return 0;
}

转载于:https://www.cnblogs.com/zhourongqing/archive/2012/09/05/2671561.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值