#include #include struct pattern { struct pattern *and; struct pattern *or; char symbol; }; typedef enum { false, true } bool; #define NewLine '\n' #define Space ' ' #define _getc getchar_unlocked() #define _putc putchar_unlocked #define _parse_integer(val, sep) \ do { \ char token; \ val = 0; \ while ((token = _getc) != sep) val = val * 10 + token - 48; \ } while (0); #define _read_string(s) \ do { \ char *p = s; \ while ((*p = _getc) != '\n') ++p; \ *p = '\0'; \ } while (0); #define _read_pattern(p) \ do { \ char token; \ bool mark = false; \ struct pattern *current = p, *old = p; \ while ((token = _getc) != NewLine) \ { \ switch (token) \ { \ case '(': \ mark = true; \ old = current; \ break; \ case ')': \ mark = false; \ current = old->and = _new_pattern(); \ break; \ default: \ current->symbol = token; \ if (mark) \ { \ current = current->or = _new_pattern(); \ } \ else \ { \ current = current->and = _new_pattern(); \ } \ } \ } \ } while (0); #define MAX_WORD_LEN (15 + 5) #define MAX_WORDS 5000 #define MAX_TEST_CASES 500 static struct pattern * _new_pattern (void) { struct pattern *p = (struct pattern *) malloc (sizeof (struct pattern)); p->and = p->or = NULL; return p; } bool pattern_match (struct pattern *p, const char *word) { struct pattern *current = p, *old; const char *pos = word; while (current != NULL) { if (*pos != current->symbol) { if (current->or != NULL) { old = current; current = current->or; while (current != NULL) { if (current->symbol == *pos) { break; } current = current->or; } if (current != NULL) { current = old; goto match; } else { return false; } } else { return false; } } else { match: current = current->and; pos = pos + 1; } } return true; } int main (int argc, char **argv) { char words[MAX_WORDS][MAX_WORD_LEN]; struct pattern patterns[MAX_TEST_CASES]; int l, d, n, i, j, c; _parse_integer (l, Space); _parse_integer (d, Space); _parse_integer (n, NewLine); for (i = 0; i < d; ++i) { _read_string (words[i]); } for (i = 0; i < n; ++i) { _read_pattern (patterns + i); c = 0; for (j = 0; j < d; ++j) { if (pattern_match (patterns + i, words[j])) { ++c; } } printf ("Case #%d: %d\n", i + 1, c); } return 0; }