【HDU】2825 Wireless Password

  1 #include<cstdio>

  2 #include<cstring>

  3 #include<queue>

  4 #define MAXN 110

  5 #define MAXM 26

  6 #define MAXL (1<<10)

  7 #define MOD 20090717

  8 using namespace std;

  9 char str[MAXN];

 10 int size, digit[MAXL], dp[30][MAXN][MAXL];

 11 struct node {

 12     int fail, end, next[MAXM];

 13     void Init() {

 14         fail = end = 0;

 15         memset(next, 0, sizeof(next));

 16     }

 17 };

 18 node tree[MAXN];

 19 inline int GET(char ch) {

 20     return ch - 'a';

 21 }

 22 void Insert(char *s, int pos) {

 23     int now, t;

 24     for (now = 0; *s; s++) {

 25         t = GET(*s);

 26         if (!tree[now].next[t]) {

 27             tree[++size].Init();

 28             tree[now].next[t] = size;

 29         }

 30         now = tree[now].next[t];

 31     }

 32     tree[now].end |= (1 << pos);

 33 }

 34 void BFS() {

 35     int now, i, p;

 36     queue<int> q;

 37     q.push(0);

 38     while (!q.empty()) {

 39         now = q.front();

 40         q.pop();

 41         for (i = 0; i < MAXM; i++) {

 42             if (tree[now].next[i]) {

 43                 p = tree[now].next[i];

 44                 q.push(p);

 45                 if (now)

 46                     tree[p].fail = tree[tree[now].fail].next[i];

 47                 tree[p].end |= tree[tree[p].fail].end;

 48             } else

 49                 tree[now].next[i] = tree[tree[now].fail].next[i];

 50         }

 51     }

 52 }

 53 void Init() {

 54     int i, k;

 55     for (i = 0; i < MAXL; i++) {

 56         digit[i] = 0;

 57         for (k = i; k; k >>= 1) {

 58             if (k & 1)

 59                 digit[i]++;

 60         }

 61     }

 62 }

 63 void DoIt(int n, int m, int t) {

 64     int i, j, k, l, p, ans;

 65     for (i = 1; i <= n; i++) {

 66         for (j = 0; j <= size; j++)

 67             memset(dp[i][j], 0, sizeof(int) * (1 << m));

 68     }

 69     dp[0][0][0] = 1;

 70     for (i = 1; i <= n; i++) {

 71         for (j = 0; j <= size; j++) {

 72             for (k = 0; k < (1 << m); k++) {

 73                 if (dp[i - 1][j][k] && (tree[j].end & k) == tree[j].end) {

 74                     for (l = 0; l < MAXM; l++) {

 75                         p = tree[j].next[l];

 76                         dp[i][p][k | tree[p].end] += dp[i - 1][j][k];

 77                         if (dp[i][p][k | tree[p].end] >= MOD)

 78                             dp[i][p][k | tree[p].end] %= MOD;

 79                     }

 80                 }

 81             }

 82         }

 83     }

 84     for (j = ans = 0; j <= size; j++) {

 85         for (k = 0; k < (1 << m); k++) {

 86             if (digit[k] >= t) {

 87                 ans += dp[n][j][k];

 88                 if (ans >= MOD)

 89                     ans %= MOD;

 90             }

 91         }

 92     }

 93     printf("%d\n", ans);

 94 }

 95 int main() {

 96     int n, m, k, i;

 97     Init();

 98     while (scanf("%d%d%d", &n, &m, &k), n) {

 99         tree[0].Init();

100         for (size = i = 0; i < m; i++) {

101             scanf(" %s", str);

102             Insert(str, i);

103         }

104         BFS();

105         DoIt(n, m, k);

106     }

107     return 0;

108 }

你可能感兴趣的:(password)