HDU 1671 Phone List(tire树)

本题题意就是给你 N个字符串 问你这几个字符串中是否存在一个为另一个的前缀,存在输出NO,不存在输出YES

这题我是学习的kuangbin的模板,用数组的话实现起来更简单。

http://www.lxway.com/68508196.htm

简单说一下val数组就是记录这一串字符的尾节点的。如果是尾节点,就是1,判断是否为前缀就是看当时他的val是否为1.

还有一种情况是现在这个字符串是其他的前缀,只需要看他后面有没有节点,扫一遍如果存在就说明他是其他字符串的前缀。

AC代码:

/* ***********************************************
Author        :yzkAccepted
Created Time  :2016/3/11 9:43:53
TASK		  :ggfly.cpp
LANG          :C++
************************************************ */

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <stack>
using namespace std;
typedef __int64 ll;
const int maxn=1001000;
int ch[maxn][11];
int val[maxn],sz,flag;
int idx(char c){
    return c-'0';
}
void init()
{
	memset(ch[0],0,sizeof(ch[0]));
	sz=1;
}
void serch(char *s)
{
	int len,u,i,j,c;
	u=0;
	len=strlen(s);
	for(i=0;i<len;i++)
	{
		c=idx(s[i]);
		
		if(!ch[u][c])
		{
			memset(ch[sz],0,sizeof(ch[sz])); 
			val[sz]=0;
			ch[u][c]=sz;
			sz++;
		}
		else
		{
			if(val[ch[u][c]])
			{
				flag=0;
				break;
			}
		}
		u=ch[u][c];
	}
	val[u]=1;
	for(i=0;i<=9;i++)
	{
		if(ch[u][i])
		{flag=0;
			break;
		}
	}
}
int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
	int n,m,i,j,t;
	char s[200];
	scanf("%d",&t);
	while(t--)
	{
		flag=1;
		scanf("%d",&n);
		init();
		for(i=1;i<=n;i++)
		{
			scanf("%s",s);
			if(flag)
				serch(s);
		}
		if(flag==0) printf("NO\n");
		else printf("YES\n");
		
	}
    return 0;
}


你可能感兴趣的:(HDU)