前阵子用Trie树过了poj2945,当然题目本身比较水,但数据量应该还是比较大的。限制时间为5秒。
4548K && 547MS
Trie树解法:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int const childnum = 4;
const int map[] = {
0, -1, 1, -1, -1, -1, 2,
-1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, 3
};
struct node {
node* child[childnum];
int times;
bool isstop;
};
const int peoplenum = 20010;
const int DNAlen = 21;
node Tree[peoplenum*DNAlen];
int nodecnt = 0;
//rec[i] contains the number of persons that are present in i identical copies
//rec[4] = 3 重复了4次的不同基因有4个
int rec[peoplenum];
char str[peoplenum][DNAlen];
void init(node *p)
{
memset(p->child, NULL, sizeof (p->child));
p->isstop = false;
p->times = 0;
}
void insert(node *p, char *s)
{
int rec = nodecnt;
for (int i = 0; s[i]; i++) {
int idx = map[s[i]-'A'];
if (p->child[idx] == NULL) {
nodecnt++;
p->child[idx] = Tree + nodecnt;
init(p->child[idx]);
}
p = p->child[idx];
}
if (p->isstop == true) {
(p->times++);
return;
}
p->isstop = true;
p->times = 1;
}
int main()
{
int n, m;
while (scanf("%d%d", &n, &m), n || m) {
node *p = Tree;
init(p);
nodecnt = 0;
for (int i = 0; i != n; i++) {
scanf("%s", str[i]);
insert(p, str[i]);
}
memset(rec, 0, sizeof (rec));
for (int i = 1; i != nodecnt+1; i++) {
if (Tree[i].isstop = true) {
rec[Tree[i].times]++;
}
}
for (int i = 1; i != n+1; i++) {
printf("%d\n", rec[i]);
}
}
return 0;
}
排序解法
最近对STL比较有兴趣,用vector<string>来解,其实就是字符串数组,结果超时了。。。不过考虑用scanf()和printf()改改再试。
结果马上换成C语言的东西来写,AC了。
1244K && 985MS
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
struct node {
char DNA[25];
};
node str[20010];
int counter[20010];
bool cmp(node a, node b)
{
for (int i = 0; i != strlen(a.DNA); i++) {
if (a.DNA[i] != b.DNA[i])
return a.DNA[i] < b.DNA[i];
}
return true;
}
int main()
{
int cnt, len, i;
while (scanf("%d%d", &cnt, &len) != EOF && cnt || len) {
for (i = 0; i != cnt; i++) {
counter[i] = 0;
memset(str[i].DNA, 0, sizeof (str[i].DNA));
}
for (i = 0; i != cnt; i++)
scanf("%s", str[i].DNA);
sort(str, str+cnt, cmp);
for (i = 0; i != len; i++) {
str[cnt].DNA[i] = 'Z';
}
str[cnt].DNA[i] = '\0';
int num = 0;
for (i = 1; i != cnt+1; i++) {
if (strcmp(str[i].DNA, str[i-1].DNA) == 0) {
num++;
}
else {
counter[num+1]++;
num = 0;
}
}
for (i = 1; i != cnt+1; i++) {
printf("%d\n", counter[i]);
}
} //while
return 0;
}
今天学了一下STL的map,使用之,写起代码来,很短很清晰!当然了,回防止超时,还是用了C语言的字符串和C的输入输出。
1892K && 1532MS
#include <iostream>
#include <cstdio>
#include <string>
#include <map>
using namespace std;
const int people = 20010;
const int DNAlen = 25;
typedef map<string, int> msi;
int cnt[people];
int main()
{
msi mapsi;
int num, len;
char tmp[DNAlen];
while (cin >> num >> len, num||len) {
mapsi.clear();
for (int i = 1; i != num+1; i++)
cnt[i] = 0;
for (int i = 0; i != num; i++) {
scanf("%s", tmp);
mapsi[tmp]++;
}
for (msi::iterator it = mapsi.begin(); it != mapsi.end(); it++)
cnt[it->second]++;
for (int i = 1; i != num+1; i++)
printf("%d\n", cnt[i]);
}
return 0;
}