poj2945

前阵子用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;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值