Hdu-1800 Flying to the Mars

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1800

题目大意:

给你一堆士兵的等级,等级高的的士兵可以当等级小的士兵的师傅,一个士兵最多一个师傅(可以没有),一个师傅最多1个徒弟(可以没有),如果是师徒关系,可以用一把扫帚练习技能,问你如果全部士兵都用过扫帚练习时最小需要的扫帚数量。

解题思路:

实质就是字典树的应用,但是要联想到字典树需要一定的基础。如果所有士兵等级都不同,则就可以用一条师徒链,所以就需要一把扫帚,而如果出现2个相同等级的士兵,则需要开辟另外一条师徒链,以此类推,发现只要求出等级相同的最多士兵数,就需要多少把扫帚。

注意地方:前导0的处理,1和01和001都是同一个数字(字符串处理,不是整型,所以必须处理前导0)。如果不处理,则需要1把扫帚,处理后才是3把扫帚。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
#define MAXN 50000
int num, maxn;

struct Dictree
{
	int num;
	Dictree *tire[30];
}*head;
Dictree Head[MAXN];

int fun(char str[]) //去掉前导的0
{
	int i, len;
	len = strlen(str);
	for(i = 0; i < len; ++i)
		if(str[i] != '0')
			break;
	return i;
}

void insert(int start, char str[]) //start为去掉前导0后的第一个位置
{
	int len, temp;
	head = &Head[0]; //字典树入口
	len = strlen(str);
	for(int i = start; i < len; ++i)
	{
		temp = str[i] - 48;
		if(head->tire[temp] == NULL)
			head->tire[temp] = &Head[++num];
		head = head->tire[temp];
	}
	if(head->num != 0)
		head->num++;	
	else
		head->num = 1;
	maxn = max(maxn, head->num); //需要的扫帚数
}

int main()
{
	int ncase;
	char str[32];
	while(scanf("%d", &ncase) != EOF)
	{
		memset(Head, 0, sizeof(Head));
		num = 0;
		maxn = 0;
		for(int i = 1; i <= ncase; ++i)
		{
			scanf("%s", str);
			insert(fun(str), str);
		}
		printf("%d\n", maxn);
	}
	return 0;
}


你可能感兴趣的:(null,insert,fun,联想)