题目描述 波波同学是位大四的学生,同时也是一位考研er。为了考上北京邮电大学,他准备了很长时间。不久前,考研成绩终于公布了。波波登陆了成绩查询网站,发现自己密码竟然忘记了!但是幸好,他还记得其中的某些字母。请你判断,他记忆中的字母是否是正确密码的片段。 输入 多组样例,每组样例有两行。第一行为正确密码,第二行为波波记得的密码片段,'*'号表示波波不知道的密码片段,可能任意长,也可能为零。每行不超过110字符,首尾不会出现'*'。 输出 对于每组样例,能得到正确密码的输出yes,不能的输出no。 样例输入 abcdefg
ab*f
fnoeend
f*ed
ajfneogbb
aj*n*b
样例输出 yes
no
yes
Source loying 昨天刚开始看到这道题的时候,觉得可以做,开始是想以 * 为分割符,把给的正确密码分成两个字符串,然后再用两个字符串和正确的密码相匹配。后来,队友给了我们一个特殊样例,比如像abcfabfe ab*fe我们按我们的思路就行不通,就换了种思路,队友说可以用最长公共子序列做,然后我们就做后面的题去了,把这道题交给他了,后来他说他的思路也错了,我们做另外一道题也没做出来。。今天看了别人的思路,其实我们按我们那种思路在想一下应该也能够想出来。 思路是这样的,进行递归匹配,分成两种情况,如果当前判断的不是 *,看两个字符串中的字符是不是相等,如果相等就递归查找 x+1,y+1; 如果是 *,这里多个*也当成一个 *处理,然后就看 x位置的字符和y+1位置的字符是否相等,如果想等就递归匹配 x+1,y+2;剩下的就是一些细节的处理了。 下面是ac的代码,参考了别人的,把第一个字符设为*; #include <cstdio>
#include <cstring>
using namespace std;
char s[120],c[120];
int cmp(int x,int y)
{
int len1,len2;
len1=strlen(s);
len2=strlen(c);
if((y<len2)&&(x>=len1)) return 0; //第一个字符串遍历完了,第二个还没完,说明就不匹配
if(y==len2) return 1; //第二个遍历完了 说明以及匹配到了
if(c[y]=='*')
{
while(c[y+1]=='*') y++; //多个* 的情况
int temp;
for(int i=x;i<len1;i++)
{
if(s[i]==c[y+1])
{
temp=cmp(i+1,y+2); //这里y是*的那个位置,所以下一个位置应该是y+2;
if(temp) return 1;
}
}
return 0;
}
else
{
if(s[x]!=c[y]) return 0;
else
return cmp(x+1,y+1);
}
}
int main()
{
while(scanf("%s\n%s",s,c+1)!=EOF)
{
c[0]='*';
puts(cmp(0,0)?"yes":"no");
}
}
这里的c[0]='*'感觉是个技巧,我把这里改了,感觉思路还是对的,样例也都通过了,但是还是wa; #include <cstdio>
#include <cstring>
using namespace std;
char s[120],c[120];
int cmp(int x,int y)
{
int len1,len2;
len1=strlen(s);
len2=strlen(c);
if((y<len2)&&(x>=len1)) return 0;
if(y==len2) return 1;
if(c[y]=='*')
{
while(c[y+1]=='*') y++;
int temp;
for(int i=x;i<len1;i++)
{
if(s[i]==c[y+1])
{
temp=cmp(i+1,y+2);
if(temp) return 1;
}
}
return 0;
}
else
{
if(s[x]!=c[y]) return 0;
else
return cmp(x+1,y+1);
}
}
int main()
{
while(scanf("%s\n%s",s,c)!=EOF) //这里变成c
{
//c[0]='*';就这里改了一下
puts(cmp(0,0)?"yes":"no");
}
}
感觉思路也还是那样,就是wa |