uestc1824 Judgment Day ——比赛残留题
April 20, 2013
uestc
题目链接: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。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <cmath>
#include <algorithm>
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
using namespace std;
typedef long long int LL;
const int MAXN = 0x3f3f3f3f;
const int MIN = -0x3f3f3f3f;
const double eps = 1e-9;
const int dir[8][2] = {{0,1},{1,0},{0,-1},{-1,0},{-1,1},
{1,1},{1,-1},{-1,-1}};
const int L = 100000+10;
char s[L], a[15][L];
int t, nn, cnt[29], ca[15][29], cc[29];
int main(void){
#ifndef ONLINE_JUDGE
freopen("j.in", "r", stdin);
#endif
int n, i, j, k, len; scanf("%d", &t);
for (i = 1; i <= t; ++i){
memset(cnt, 0, sizeof(cnt));
scanf("%s", s); len = strlen(s);
for (k = 0; k < len; ++k){
cnt[s[k]-'a']++;
}
scanf("%d", &nn);
memset(ca, 0, sizeof(ca));
for (j = 1; j <= nn; ++j){
scanf("%s", a[j]); len = strlen(a[j]);
for (k = 0; k < len; ++k){
ca[j][a[j][k]-'a']++;
}
}
int max = 0, count = 0;
for (int x = 1; x <= (1<<nn)-1; ++x){
for (int s = 0; s <= 25; ++s) cc[s] = cnt[s];
count = 0;
for (int j = 0; j <= nn-1; ++j){
int pos = (1<<j)&x;
if (pos){
int kk;
for (kk = 0; kk <= 25; ++kk){
if (ca[j+1][kk]){
if (ca[j+1][kk] <= cc[kk]) {
cc[kk] -= ca[j+1][kk];
}
else break;
}
}
if (kk == 26) count++;
}
}
if (count > max) max = count;
}
printf("Case #%d: %d\n", i, max);
}
return 0;
}
写的过程中还是花了不少时间,有一些小细节,虽然明白,但是还是用错了,属于一些低级错误。还是代码能力不够吧。 这是昨天比赛的一道题目,开始读错题目了,以为KMP,后来才发现不是,然后终于弄懂题目意思了,可是没注意到10这个条件,不知道用枚举,唉…… 以后读题至少要读清楚!