HDU-2572-终曲

终曲

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1425    Accepted Submission(s): 416


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
 

Author
yifenfei
 

Source
 

Recommend
yifenfei   |   We have carefully selected several similar problems for you:   2609  2544  2700  2602  2600 

仙剑A题录终于刷到最后一关了.
运用了str.substring(beginIndex, endIndex);
取str字符串中的子串,从下标为beginIndex取起,endIndex结束.
这个函数省去了很多工作.
题目要求说出第一个字符串的子串,要求该子串包含第二个字符串和第三个字符串.
并且要求该子串的长度最小.这里注意一点.字符串本身也属于这个字符串本身最长的子串.
也就是说答案是可以和第一个字符串相匹配的.这里用一个二重循环可以获取当前s1字符串的所有子串.
public int indexOf(int ch)返回指定字符在此字符串中第一次出现处的索引.如果没有出现则返回-1.
如果当前子串包含s1,s2.即indexof得返回值都不为-1.str=s;确定当前子串,输出!如果str没有变化即子串可能与原串
相等,或者子串不匹配!输出No!

Java:
import java.io.*;
import java.util.*;

public class Main
{

	public static void main(String[] args)
	{
		// TODO Auto-generated method stub
		Scanner input = new Scanner(System.in);
		int t = input.nextInt();
		input.nextLine();
		for (int i = 0; i < t; i++)
		{
			String s;
			String s1 = input.nextLine();
			String s2 = input.nextLine();
			String s3 = input.nextLine();
			int n = s1.length();
			String str = s1 + '#';
			for (int j = 0; j < n; j++)
			{
				for (int k = j + 1; k <= n; k++)
				{
					s = s1.substring(j, k - 1);
					if (s.indexOf(s2) != -1 && s.indexOf(s3) != -1)
					{
						if (s.length() < str.length())
						{
							str = s;
						} 
						else if (s.length() == str.length())
						{
							str = s;
						}
					}
				}
			}
			if (str.length() == n + 1)
				System.out.println("No");
			else
			{
				System.out.println(str);
			}
		}
	}

}

博主大牛代码!
C:

#include<cstdio>  
#include<cstring>  
#include<algorithm>  
using namespace std;  
char s1[1010],s2[1010],s3[1010];  
struct ST  
{  
    int st;  
    int end;  
}e1[1010],e2[1010];  
struct MS  
{  
char s[110];   
}e[1010];  
int cmp(MS a,MS b)  
{  
    int x=strlen(a.s),y=strlen(b.s);  
    if(x==y)  
       return strcmp(a.s,b.s)<0;  
       else return x<y;   
}   
int main()  
{  
    int i,j,k,k1,k2,T,t,a,b,l;  
    int str[100];  
    scanf("%d",&T);  
    while(T--)  
    {  
        memset(s1,0,sizeof(s1));  
        memset(s2,0,sizeof(s2));  
        memset(s3,0,sizeof(s3));  
        scanf("%s %s %s",s1,s2,s3);  
        int len1=strlen(s1),len2=strlen(s2),len3=strlen(s3);  
        i=j=k1=0;  
        while(i<len1)  
        {          //将模式串在目标串中的位置统计出来   
            j=0;  
            t=i;  
            while(s2[j]==s1[t]&&j<len2)  
            {  
                j++;  
                t++;  
            }  
          // printf("%d--\n",j);  
            if(j==len2)  
            {  
                e1[k1].end=t-1;  
                e1[k1].st=e1[k1].end-len2+1;  
                k1++;  
            }  
            i++;  
        }            
        i=j=k2=0;  
        while(i<len1)  
        {       //将模式串在目标串中的位置统计出来   
            j=0;  
            t=i;  
            while(s3[j]==s1[t]&&j<len3)  
            {  
                j++;  
                t++;  
            }  
          //  printf("%d--\n",j);  
            if(j==len3)  
            {  
                e2[k2].end=t-1;  
                e2[k2].st=e2[k2].end-len3+1;  
                k2++;  
            }  
            i++;  
        }  
       for(i=0,k=0; i<k1; i++)  
       {  
            for(j=0; j<k2; j++)  
            {  
                a=min(e1[i].st,e2[j].st);  
                b=max(e1[i].end,e2[j].end);  
                for(l=0;a<=b;a++) e[k].s[l++]=s1[a];  
                e[k++].s[l]='\0';              //求出包含两个字符串的子串   
            }  
        }  
        sort(e,e+k,cmp);               //排序,先排长度,再排字典序   
        if(k==0) printf("No\n");   
        else  
        {  
            printf("%s",e[0].s);  
            printf("\n");  
        }  
          
    }  
    return 0;  
} 

C++:(用G++提交!用到了G++特性!)

#include<cstring>
#include<iostream>
using namespace std;
int main()
{
    int T,i,j,n;
    cin>>T;
    while(T--)
    {
        string s,s1,s2,s3,str;    //str起临时存储的作用 
        cin>>s1>>s2>>s3;
        n=s1.length();
        str=s1+"#";            
        for(i=0; i<n; i++)
        {
            for(j=i+1; j<=n; j++)
            {
                s=s1.substr(i,j-i);   //substr是C++语言函数,主要功能是复制子字符串,要求从指定位置开始,并具有指定的长度。
                if(s.find(s2)!=-1&&s.find(s3)!=-1)  //未找到s2、s3则返回-1 
                {          
                    if(s.length()<str.length())
                    {
                        str=s;
                    }
                    else if(s.length()==str.length())
                    {
                        if(s<str)
                        str=s;
                    }
                }
            }
        }
        if(str.length()==n+1) cout<<"No"<<endl;
        else 
        cout<<str<<endl;
    }
    return 0;
}

跪跪跪神牛!Orz!!!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值