IOI96 最長前綴

P1809【USACO2.3.1】Longest Prefix最長前綴 IOI’96

時間限制 : 15000 MS 空間限制 : 65536 KB

問題描述 
在生物學中,一些生物的結構是用包含其要素的大寫字母序列來表示的。生物學家對於把長的序列分解成較短的序列(即元素)很感興趣。 
如果一個集合 P 中的元素可以通過串聯(元素可以重複使用,相當於 Pascal 中的 “+” 運算符)組成一個序列 S ,那麼我們認爲序列 S 可以分解爲 P 中的元素。元素不一定要全部出現(如下例中BBC就沒有出現)。舉個例子,序列 ABABACABAAB 可以分解爲下面集合中的元素: 
{A, AB, BA, CA, BBC} 
序列 S 的前面 K 個字符稱作 S 中長度爲 K 的前綴。設計一個程序,輸入一個元素集合以及一個大寫字母序列 S ,設S’是序列S的最長前綴,使其可以分解爲給出的集合P中的元素,求S’的長度K。

輸入格式 
輸入數據的開頭包括 1..200 個元素(長度爲 1..10 )組成的集合,用連續的以空格分開的字符串表示。字母全部是大寫,數據可能不止一行。元素集合結束的標誌是一個只包含一個 “.” 的行。集合中的元素沒有重複。接着是大寫字母序列 S ,長度爲 1..200,000 ,用一行或者多行的字符串來表示,每行不超過 76 個字符。換行符並不是序列 S 的一部分。

輸出格式 
只有一行,輸出一個整數,表示 S 符合條件的前綴的最大長度。

樣例輸入 
A AB BA CA BBC 

ABABACABAABC

樣例輸出 

11

#include<cstdio>
#include<cstring>
#include<string.h>
#include<iostream>
using namespace std;
string a[201];
string str;
bool f[200001];
int n,len;
bool ischar(char c)
{
	if(c>='A'&&c<='Z')
	return true;
	return false;
}

bool check(int p)
{
	int t;
	for(int i=1;i<=n;i++)
	{
		t=a[i].length();
		if(p>=t)
		{
			if(a[i]==str.substr(p-t+1,t))
			if(f[p-t])
			return true;
		}
	}
	return false;
}

int main()
{
	string s;
	n=0;
	while(cin>>s,s!=".")
	{
		n++;
		a[n]=s;
	}
	int x1,x2;
    str="";
	len=0;
	while(cin>>s)
	{
		x1=0;
		x2=s.length()-1;
		while(!ischar(s[x1]))
		x1++;
		while(!ischar(s[x2]))
		x2--;
		str+=s.substr(x1,x2-x1+1);
		len+=x2-x1+1;
	}
	memset(f,0,sizeof(f));
	f[0]=true;
	for(int i=1;i<=len;i++)
	if(check(i))
	f[i]=true;
	else
	f[i]=false;
	for(int i=len;i>=0;i--)
	if(f[i]){
		cout<<i<<endl;
		break;
	}
	return 0;
}


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