HDU6170 Two strings dp 多校联赛第9场

7 篇文章 0 订阅

Two strings

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1662    Accepted Submission(s): 655


Problem Description
Giving two strings and you should judge if they are matched.
The first string contains lowercase letters and uppercase letters.
The second string contains lowercase letters, uppercase letters, and special symbols: “.” and “*”.
. can match any letter, and * means the front character can appear any times. For example, “a.b” can match “acb” or “abb”, “a*” can match “a”, “aa” and even empty string. ( “*” will not appear in the front of the string, and there will not be two consecutive “*”.
 

Input
The first line contains an integer T implying the number of test cases. (T≤15)
For each test case, there are two lines implying the two strings (The length of the two strings is less than 2500).
 

Output
For each test case, print “yes” if the two strings are matched, otherwise print “no”.
 

Sample Input
      
      
3 aa a* abb a.* abb aab
 

Sample Output
      
      
yes yes no


题意是  给你一个匹配串,看你能不能匹配原串,   在题目中的匹配字符有俩个:

'.'可以匹配任何字符

'*'可以匹配它之前的一个字符任意次,可以为0

设置两个串,分别是a串b串,分别代表原串和匹配串,令dp[i][j]代表b串中1-i到a串中的1-j中的字符是否匹配,有以下转移关系:

1.当b[i]=='.' 或者b[i]==a[i]时,此时dp[i][j]=dp[i-1][j-1];

2. 当 b[i]== 时,则匹配一个或者不匹配都合法,那么就由 dp[i2][j] dp[i1][j] 转移而来,因为 可以匹配任意数量的字符,所以还要判断假如  a[j1]b[i1]  已成功匹配,并且 a[j1]==a[j] ,显然当前的 * 可以继续匹配这一个字符,因此  dp[i][j]=true  ,假如  a[j1]b[i]  已成功匹配(当前 * 已成功匹配若干位),且  a[j1]==a[j]  ,则可以继续匹配这一个字符,因此 dp[i][j]=true  。





#include <cstdio>
#include <cstring>
#include <cctype>
#include <string>
#include <set>
#include <iostream>
#include <stack>
#include <cmath>
#include <queue>
#include <vector>
#include <algorithm>
#define mem(a,b) memset(a,b,sizeof(a))
#define inf 0x3f3f3f3f
#define mod 1000007
#define ll long long
using namespace std;
const int N=2500+10;
char a[N],b[N];
bool dp[N][N];
int main()
{
    int t;
    scanf("%d",&t);
    getchar();
    while(t--)
    {
        mem(dp,0);
        a[0]=b[0]='0';
        gets(a+1);
        gets(b+1);
        int lena=strlen(a)-1;
        int lenb=strlen(b)-1;
        dp[0][0]=true;
        for(int i=1;i<=lenb;i++)
        {
            if(i==2&&b[i]=='*')
                dp[2][0]=true;
            for(int j=1;j<=lena;j++)
            {
                if(b[i]=='.'||b[i]==a[j])
                    dp[i][j]=dp[i-1][j-1];
                else if(b[i]=='*')
                {
                    dp[i][j]=dp[i-2][j]|dp[i-1][j];
                    if((dp[i-1][j-1]||dp[i][j-1])&&a[j-1]==a[j])//匹配连续的*
                        dp[i][j]=true;
                }
            }
        }
        if(dp[lenb][lena])puts("yes");
        else puts("no");
    }
  return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值