hdu6170

博客介绍了HDU6170编程题的解决方案,该题要求处理两个字符串,其中一个包含'*'和'.'特殊字符。'*'能匹配任意次数的前一个字符,'.'能匹配任意字符。任务是判断两个字符串是否能匹配。文章提到了使用Java正则表达式、模拟和动态规划(DP)等多种解法,并详细阐述了DP的方法,包括状态定义和转移过程。
摘要由CSDN通过智能技术生成

HDU6170 Two strings

题目链接
题意是给两个串,第一个串是只包括大小写字母的串,第二个串除了大小写字母还包含了 ” * ” “.” 。 “.”可以匹配任意字符 ,“ * ”可以让前面的字符出现任意次,包括0次。 问这两个串能不能匹配上。
这道题有很多种解法,用java正则或者模拟或者dp都行。
给出dp做法,dp[i][j][0/1/2]代表第一串前i个和第二串前j个且第二个串能否匹配上,[0/1/2]分别代表第二个串第j个字符为*时,使前面第一个字符出现超过1次/1次/0次 ,然后就可以dp转移了

 #include<cmath>
#include<algorithm>
#include<cstring>
#include<string>
#include<set>
#include<map>
#include<time.h>
#include<cstdio>
#include<vector>
#include<list>
#include<stack>
#include<queue>
#include<iostream>
#include<stdlib.h>
using namespace std;
#define  LONG long long
const LONG  INF=0x3f3f3f3f;
const LONG  MOD=1e9+7;
const double PI=acos(-1.0);
#define clrI(x) memset(x,-1,sizeof(x))
#define clr0(x) memset(x,0,sizeof x)
#define clr1(x) memset(x,INF,sizeof x)
#define clr2(x) memset(x,-INF,sizeof x)
#define EPS 1e-10
#define lson  l , mid , rt<< 1
#define rson  mid + 1 ,r , (rt<<1)|1
#define root 1, n , 1
bool dp[2650][2600][3] ;
char str1[2510]  ;
char str2[2510] ;
int main()
{
    int T ;
    cin >> T ;
    while(T --)
    {
        str1[0] = str2[0] = '#' ;
        scanf("%s%s",str1 + 1,str2+1) ;
        int n = strlen(str1) - 1;
        int m = strlen(str2) - 1;
        clr0(dp ) ;
        dp[0][0][0] = 1;
        dp[0][0][1] = 1;
        dp[0][0][2] = 1;
        for(int i = 0 ; i<= n ; ++ i )
        {
            for(int j = 0 ; j<= m ; ++ j )
            {
                if(str2[j]== '.')
                {
                    dp[i][j][0] |= ( dp[i-1][j-1][0] |dp[i-1][j-1][1]|dp[i-1][j-1][2] )  ;
                    dp[i][j][1] = dp[i][j][0] ;
                    dp[i][j][2] = dp[i][j][0] ;
                }
                else if(str2[j] != '*')
                {
                    if(str1[i] == str2[j])
                        dp[i][j][0] |= ( dp[i-1][j-1][0] |dp[i-1][j-1][1]|dp[i-1][j-1][2] )  ;
                    dp[i][j][1] = dp[i][j][0] ;
                    dp[i][j][2] = dp[i][j][0] ;
                }
                else
                {
                    if( i>=1&&str1[i-1] == str1[i] )
                        dp[i][j][0] |=(dp[i-1][j][0]),
                    dp[i][j][0] |= (dp[i-1][j-1][0] | dp[i-1][j-1][1] | dp[i-1][j-1][2]) ;
                    dp[i][j][1] |= (dp[i][j-1][0]|dp[i][j-1][1]|dp[i][j-1][2]) ;
                    dp[i][j][2] |= (dp[i][j-2][0] | dp[i][j-2][1] | dp[i][j-2][2] ) ;
                }
            }
        }
        int ans = (dp[n][m][0] | dp[n][m][1] | dp[n][m][2] ) ;
        if(ans)
            cout<<"yes"<<endl;
        else cout<<"no"<<endl;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值