终曲(hdu 2572)解题报告

Problem Description

最后的挑战终于到了!
站在yifenfei和MM面前的只剩下邪恶的大魔王lemon一人了!战胜他,yifenfei就能顺利救出MM。
Yifenfei和魔王lemon的挑战很简单:由lemon给出三个字符串,然后要yifenfei说出第一串的某个子串,要求该子串长度最小,并且同时包含第2个串和第3个串。
特别地,如果有多个这样的子串,则请输出字母序最小的一个。

Input

输入数据首先是一个整数C,表示测试数据有C组;
接着是C组数据,每组包含三行字符串,第一个字符串长度大于1小于100
后面两个串的长度大于1且小于10

Output

请对应每组输入数据输出满足条件的最短子串;
如果没有,请输出 No

Sample Input

2

abcd

ab

bc

abc

ab

bd

Sample Output

abc

No

思路:

因为str2和str3的长度小于等于10,所以求str1中包含str2和str3的子串就直接用strstr函数了。

下面看一个例子

Str1:abdedbcabcde

Str2:ab

Str3:bc

a

b

d

e

d

b

c

a

b

c

d

e

↑p

                     
         

↑q

           

设p为Str2在Str1中出现的位置指针,而q为str3在Str1中出现的位置指针。

用strstr可分别求出p,q的初始值。p&&q为0说明不存在这样的子串。

比较p,q的大小可确定子串的内容。

如上表该子串为:”abdedbc” 即头元素的位置为p,长度为 q-p+strlen(str3)。

因p<q,所以继续查找str2在str1中出现的下一个位置。

直到p或者q为null。

好了找到所有满足条件的子串没有,现在问题的关键是要找出所有最短的子串。最简单的方法就是保存所有满足条件的子串,然后按长度排序。这里要注意的是当长度相同的时候,要按字典序比较字符串。

结论:用strstr求出满足条件的子串,然后用set容器找出最短子串。

代码:

#include <string>

#include <iostream>

#include <string.h>

#include <set>

using namespace std;

struct comp

{

bool operator()(const string &a ,const string & b)

{

if(a.length()==b.length())

return a.compare(b);

return a.length()<b.length();

}

};

int main()

{

int n,l1,l2,l3;

char s1[101],s2[11],s3[11],st[101],*p,*q;

set <string,comp>an;

string ss;

cin>> n;

while (n--)

{

cin >> s1>>s2>>s3;

l1=strlen(s1);

l2=strlen(s2);

l3=strlen(s3);

p=q=s1;

p=strstr(p,s2);

q=strstr(q,s3);

if(p && q)

{

while(p && q)

{

if(p<q)

{

strncpy(st,p,q-p+l3);

st[q-p+l3]='\0';

p=strstr(p+1,s2);

}

else

{

strncpy(st,q,p-q+l2);

st[p-q+l2]='\0';

q=strstr(q+1,s3);

}

ss=st;

an.insert(ss);

}

cout << *an.begin() << endl;

}

else

cout << "No" << endl;

an.clear();

}

return 0;

}

posted on 2010-07-23 00:02  网络小筑  阅读(313)  评论(0编辑  收藏  举报

导航