`
Simone_chou
  • 浏览: 184556 次
  • 性别: Icon_minigender_2
  • 来自: 广州
社区版块
存档分类
最新评论

Longest Prefix(字典树 + DFS + 剪枝)

 
阅读更多
Longest Prefix
IOI'96

The structure of some biological objects is represented by the sequence of their constituents, where each part is denoted by an uppercase letter. Biologists are interested in decomposing a long sequence into shorter sequences 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 sequence ABABACABAABcan 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

 

    题意:

    给出一系列单词(1 ~ 200),每个单词长度 1 ~ 10,直到输入“ . ”表示结束。后给出一个字符串(1 ~ 200000),输出字符串最长的前缀长度,这个前缀能由给出的单词组成。

 

    思路:

    字典树存储单词,后在字典树上DFS,同时剪枝。标记单词构成的每段字符串来剪枝,不然会超时。

 

    AC:

/*
TASK:prefix
LANG:C++
ID:sum-g1
*/
#include <string.h>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef struct no
{
    struct no *next[30];
    int temp;
}node;
char aim[200050];
int test[200050];
int max_len,len;

node *creat_node()
{
    node *p = new node;
    for(int i = 0;i < 30;i++)
        p -> next[i] = NULL;

    p -> temp = 0;
    return p;
}

void insert_str(char *str,node *head)
{
    int str_len = strlen(str);
    node *p = head;
    for(int i = 0;i < str_len;i++)
    {
        int c = str[i] - 'A';
        if(p -> next[c] == NULL)
            p -> next[c] = creat_node();

        p = p -> next[c];
    }

    p -> temp = 1;
    return;
}

void dfs(int idex,node *head)
{
    if(idex > max_len) max_len = idex;
    if(idex == len)    return;
//若当前下标等于目标串长度则返回
    if(test[idex]) return;
    test[idex] = 1;   //test 数组标记状态
    int i = idex,k = aim[i] - 'A';
    node *p = head;
    while(p -> next[k] != NULL)
    {
        i++;
        p = p -> next[k];
        if(i < len)     k = aim[i] - 'A';
//若i == len时也访问数组的话会数组越界
        if(p -> temp)   dfs(i,head);
//凡是单词都搜索一遍,以下一个下标开始
//若是最后一个字母也会进行向下搜索
        if(!p -> temp && i == len)  return;
//当为最后一个字母却不是单词时返回
    }

    return;
}

int main()
{
    freopen("prefix.in","r",stdin);
    freopen("prefix.out","w",stdout);
    char vab[50],str[200];
    node *head = creat_node();
    max_len = 0;
    memset(test,0,sizeof(test));
    while(~scanf("%s",vab) && vab[0] != '.')
    {
        insert_str(vab,head);
    }

    while(~scanf("%s",str))
    {
        strcat(aim,str);
    }
    len = strlen(aim);
    dfs(0,head);
    printf("%d\n",max_len);
    return 0;
}

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics