官方题解的java版本,加了点细节。
题目里比较容易引起歧义的应该是匹配的定义吧,需要的是完全覆盖,就是s变换以后不能比m长也不能比m短,就是刚好覆盖才算匹配。
import java.util.Scanner; public class Main { static String s1,s2; public static boolean dfs(int i,int j,int cur){ if(j==s2.length() && i==s1.length()) //两个值都记录到两个串的末尾加1还没有找到不匹配的,则返回匹配 return true; if(i==s1.length()) //表达串到底但数字串没到 return false; if(j<s2.length() && s1.charAt(i)==s2.charAt(j)){ //j<s2.length()是比c++版多的地方,不加会越界报错 return dfs(i+1,j+1,(s2.charAt(j)-'0'+cur)%10); //值相等就同时匹配下一个 }else if (j<s2.length() && s1.charAt(i)=='*'){ //找到* return cur==s2.charAt(j)-'0'?dfs(i+1,j+1,cur%10)||dfs(i,j+1,cur%10):false; //余数等于数字串的当前值时判断下一个,否则直接返回不匹配 } return false; } public static boolean re(){ if(s1.length()>s2.length()) return false; //当表达式比数字串更长时,显然做不到完全覆盖 for(int i=0;i<s2.length();i++){ if(s2.charAt(i)<'0' || s2.charAt(i)>'9') return false; //数字串里不能有数字以外的东西 } int i=0; for(;i<s1.length();i++){ //*在最前面的情况,记录有i个* if(s1.charAt(i)!='*') break; } s1=s1.substring(i); //i个*在最前面相当于两个字符串前i个值都可以删掉 s2=s2.substring(i); if((s1=="" && s2!="")||(s2=="" && s1!="")) return false; //删完以后如果只有一个是空串就返回不匹配 return dfs(0,0,0); } public static void main(String[] args) { //初始化的过程 Scanner in = new Scanner(System.in); int n=in.nextInt(); if (n==0) System.exit(0); in.nextLine(); while (in.hasNextLine()) { s1=in.nextLine(); if (s1.equals("0")) System.exit(0); s2=in.nextLine(); n--; if(n>=0){ boolean flag=re(); if (flag){ System.out.println("YES"); }else{ System.out.println("NO"); } } } in.close(); } }