uestc1824 Judgment Day ——比赛残留题

题目链接:http://www.acm.uestc.edu.cn/problem.php?pid=1824

题目大意:

  给一个大的字符串,给一个数字n,然后给出n个小的字符串,在大的字符串里面每个字母只能选一次,问最多可以组成多少个小的字符串。小的字符串最多有10个,每个小字符串和大字符串长度最多10000。

题目思路:

  因为最多有10个小的字符串,从10个里面选,最多有1024种选法。因为字符串只包含26个小写字母,可以统计每个小字符串里面的每个小写字母的个数,这样,复杂度大约在10×26×1024,是10^5的范围,可以枚举。

  比如对于n个字符串,最多有1<<n种,用 x 从1枚举到1<<n - 1,然后用 j 从 0 枚举到n-1,用 1 << j 和 x 相与,如果为1,则 j +1 表示第 j + 1 个人被选上了,判断它是不是能被选上,如果能被选上,那么 cnt++,再和max相比较,最后得到max。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #include <cstring>
 5 #include <cctype>
 6 #include <stack>
 7 #include <queue>
 8 #include <map>
 9 #include <set>
10 #include <vector>
11 #include <cmath>
12 #include <algorithm>
13 #define lson l, m, rt<<1
14 #define rson m+1, r, rt<<1|1
15 using namespace std;
16 typedef long long int LL;
17 const int MAXN =  0x3f3f3f3f;
18 const int  MIN =  -0x3f3f3f3f;
19 const double eps = 1e-9;
20 const int dir[8][2] = {{0,1},{1,0},{0,-1},{-1,0},{-1,1},
21   {1,1},{1,-1},{-1,-1}};
22 const int L = 100000+10;
23 char s[L], a[15][L];
24 int t, nn, cnt[29], ca[15][29], cc[29];
25 int main(void){
26 #ifndef ONLINE_JUDGE
27   freopen("j.in", "r", stdin);
28 #endif
29   int n, i, j, k, len; scanf("%d", &t);
30   for (i = 1; i <= t; ++i){
31     memset(cnt, 0, sizeof(cnt));
32     scanf("%s", s); len = strlen(s);
33     for (k = 0; k < len; ++k){
34       cnt[s[k]-'a']++;
35     }
36     scanf("%d", &nn);
37     memset(ca, 0, sizeof(ca));
38     for (j = 1; j <= nn; ++j){
39       scanf("%s", a[j]); len = strlen(a[j]);
40       for (k = 0; k < len; ++k){
41         ca[j][a[j][k]-'a']++;
42       }
43     }
44     int max = 0, count = 0;
45     for (int x = 1; x <= (1<<nn)-1; ++x){
46       for (int s = 0; s <= 25; ++s) cc[s] = cnt[s];
47       count = 0;
48       for (int j = 0; j <= nn-1; ++j){
49         int pos = (1<<j)&x;
50         if (pos){
51           int kk;
52           for (kk = 0; kk <= 25; ++kk){
53             if (ca[j+1][kk]){
54               if (ca[j+1][kk] <= cc[kk]) {
55                 cc[kk] -= ca[j+1][kk];
56               }
57               else break;
58             }
59           }
60           if (kk == 26) count++;
61         }
62       }
63       if (count > max) max = count;
64     }
65     printf("Case #%d: %d\n", i, max);
66   }
67 
68   return 0;
69 }

  写的过程中还是花了不少时间,有一些小细节,虽然明白,但是还是用错了,属于一些低级错误。还是代码能力不够吧。

  这是昨天比赛的一道题目,开始读错题目了,以为KMP,后来才发现不是,然后终于弄懂题目意思了,可是没注意到10这个条件,不知道用枚举,唉……

  以后读题至少要读清楚!

posted on 2013-04-20 09:30  aries__liu  阅读(190)  评论(0编辑  收藏  举报