啥也不说了,比较烦的DP,参考了别人的方法 代码: #include<cstdio> #include<cstring> using namespace std; struct In{ char *arr[256], line[256]; int cnt; }in[2]; enum node_type{ ONE, ZERO_ONE, ANY, STR, END }; struct node{ node_type type; char *str; }stk[2][512]; int dp[512][512],tm; void input(In *t) { scanf("%s",t->line); int i; for(t->cnt=i=0;t->line[i];i++) { t->arr[t->cnt++]=&t->line[i]; while(t->line[i] && t->line[i]!='.') i++; t->line[i]=0; } } void init(In *t, node *s) { for(int i=0;i<t->cnt;i++) { switch(*t->arr[i]){ case '*': s->type=ONE; s++; s->type=ANY; s++; break; case '?': s->type=ONE; s++; s->type=ZERO_ONE; s++; s->type=ZERO_ONE; s++; break; case '!': s->type=ONE; s++; s->type=ONE; s++; s->type=ONE; s++; s->type=ANY; s++; break; default: s->type=STR; s->str=t->arr[i]; s++; break; } } s->type=END; } int visited(node *a,node *b) { return dp[a - stk[0]][b - stk[1]] == tm; } void set_visited(node *a, node *b) { dp[a - stk[0]][b - stk[1]] = tm; } bool match(node *a,node *b) { bool r=false; if(visited(a,b)==true) return false; /********************下面是DP******************/ if (a->type == ONE) { if (b->type == ONE) r = match(a + 1, b + 1); if (b->type == ZERO_ONE) r = match(a, b + 1) || match(a + 1, b + 1); if (b->type == ANY) r = match(a, b + 1) || match(a + 1, b) || match(a + 1, b + 1); if (b->type == STR) r = match(a + 1, b + 1); if (b->type == END) r = false; } if (a->type == ZERO_ONE) { if(b->type == ONE) r = match(a+1, b) || match(a + 1, b + 1); if (b->type == ZERO_ONE) r = match(a + 1, b) || match(a, b + 1) || match(a + 1, b + 1); if (b->type == ANY) r = match(a + 1, b) || match(a, b + 1) || match(a + 1, b + 1); if (b->type == STR) r = match(a + 1, b + 1); if (b->type == END) r = match(a + 1, b); } if (a->type == ANY) { if (b->type == ONE) r = match(a, b + 1) || match(a + 1, b) || match(a + 1, b + 1); if (b->type == ZERO_ONE) r = match(a + 1, b) || match(a, b + 1) || match(a + 1, b + 1); if (b->type == ANY) r = match(a + 1, b) || match(a, b + 1) || match(a + 1, b + 1); if (b->type == STR) r = match(a + 1, b) || match(a, b + 1) || match(a + 1, b + 1); if (b->type == END) r = match(a + 1, b); } if (a->type == STR) { if (b->type == ONE) r = match(a + 1, b + 1); if (b->type == ZERO_ONE) r = match(a + 1, b + 1); if (b->type == ANY) r = match(a + 1, b) || match(a, b + 1) || match(a + 1, b + 1); if (b->type == STR) r = !strcmp(a->str, b->str) ? match(a + 1, b + 1) : 0; if (b->type == END) r = false; } if (a->type == END) { if (b->type == ONE) r = false; if (b->type == ZERO_ONE) r = match(a, b+1); if (b->type == ANY) r = match(a, b+1); if (b->type == STR) r = false; if (b->type == END) r = true; } /**********************DP THE END*******************/ if(!r) set_visited(a,b); return r; } int main() { int cas; scanf("%d",&cas); tm=0; while(cas--) { input(&in[0]); input(&in[1]); init(&in[0],stk[0]); init(&in[1],stk[1]); tm++; printf("%s/n",match(stk[0],stk[1])?"YES":"NO"); } return 0; }