对答案
题目描述
企鹅豆豆做完了作业,找你帮他检查。豆豆写的作业由小写字母组成。但由于一道题有多种答案,所以答案中除了小写字母以外还有’.’
和’*’
。
‘.’
字符可以变成任意一个小写字母。
‘x*’
可以变成‘’
(空串)、‘x’
、‘xx’
、‘xxx’
等等,即可以变任意个字符 (x)(其中 (x) 可以是小写字符或者’.’
)
现在,有标准答案以及豆豆的作业,请你判断豆豆的作业是不是完全正确的。
数据保证*
不会出现在开头,不会有两个连续的*
。
输入说明
第一行一个整数 (T),表示数据组数。
对于每组数据,第一行一个字符串,表示豆豆的作业。第二行一个字符串,表示答案。
输出说明
对于每组数据,输出一行一个字符串,如果作业正确输出“yes”
,否则输出“no”
(不含引号)
数据规模及约定
对于(30\%)的数据,字符串长度(le 10);
对于(70\%)的数据,字符串长度(le 200);
对于(100\%)的数据,字符串长度(le 2500), (Tle 15);
思路:(dp)
令(dp_{i,j})代表作业串(a)匹配到(i)答案串(b)匹配到(j)时是否可以匹配上。
有转移
(dp_{i,j}=dp_{i-1,j}|dp_{i-1,j-1} , t{if a_i = a_{i-1} && b_j='*'})
(dp_{i,j}=dp_{i-1,j-1} t{if a_i=b_j || b_j ='.'})
(dp_{i,j}=dp_{i,j-2} t{if b_j='*'})
Code:
#include <cstdio>
#include <cstring>
const int N=2502;
int dp[N][N],n,T,len1,len2;
char a[N],b[N];
int main()
{
scanf("%d",&T);
while(T--)
{
memset(dp,0,sizeof(dp));
scanf("%s%s",a+1,b+1);
dp[0][0]=1;
len1=strlen(a+1),len2=strlen(b+1);
for(int i=1;i<=len1;i++)
for(int j=1;j<=len2;j++)
{
if(a[i]==a[i-1]&&b[j]=='*')
dp[i][j]|=dp[i-1][j-1]|dp[i-1][j];
if(a[i]==b[j]||b[j]=='.')
dp[i][j]|=dp[i-1][j-1];
if(b[j]=='*'&&j>=2)
dp[i][j]|=dp[i][j-2];
}
if(dp[len1][len2]) puts("yes");
else puts("no");
}
return 0;
}
2018.11.7