查询成绩 |
||
Accepted : 52 | Submit : 275 | |
Time Limit : 3000 MS | Memory Limit : 65536 KB |
题目描述波波同学是位大四的学生,同时也是一位考研er。为了考上北京邮电大学,他准备了很长时间。不久前,考研成绩终于公布了。波波登陆了成绩查询网站,发现自己密码竟然忘记了!但是幸好,他还记得其中的某些字母。请你判断,他记忆中的字母是否是正确密码的片段。 输入多组样例,每组样例有两行。第一行为正确密码,第二行为波波记得的密码片段,‘*‘号表示波波不知道的密码片段,可能任意长,也可能为零。每行不超过110字符,首尾不会出现‘*‘。 输出对于每组样例,能得到正确密码的输出yes,不能的输出no。 样例输入abcdefg ab*f fnoeend f*ed ajfneogbb aj*n*b 样例输出yes no yes Sourceloying
昨天刚开始看到这道题的时候,觉得可以做,开始是想以 * 为分割符,把给的正确密码分成两个字符串,然后再用两个字符串和正确的密码相匹配。后来,队友给了我们一个特殊样例,比如像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 |
XTU OJ 1163 查询成绩 (字符串+递归)
时间: 2024-10-09 04:57:39