现在的位置: 首页 > 综合 > 正文

SWUN 1308 – 野蛮的城管

2013年05月30日 ⁄ 综合 ⁄ 共 1486字 ⁄ 字号 评论关闭


野蛮的城管

时间限制(普通/Java) : 1000 MS/ 3000 MS          运行内存限制 : 181920 KByte
总提交 : 21            测试通过 : 4

描述

 

     在传说中的粉刷街上,墙上充斥着各种各样的彩色词汇。

但在这条街上,新任城管chc突然野蛮的认定了某些词汇是不应该存在的,于是要求RSS将那些词汇统计数量并上报。

当然chc的风骚你们是不懂的,他要求RSS只要看到任何一个单词中包含该词汇就必须统计上,比如babs中就会被认定为含有abs这个单词。

现在邪恶的CHC想知道 RSS统计某个词汇的数量。

被痛苦摧残的RSS请求你的帮助。

 

输入

第一行是个数字N,代表这条街上有N个词汇。

接下来N行,每行有一个字符串。

接下来一行是一个整数M,表示有M次统计。

然后是M行字符串,代表需要被统计的单词。

(1<=N<=10000,1<=M<=100000,字符串长度不超过20,但大小写敏感)

 

输出

对应每次统计,输出一次城管们的统计数字。

样例输入

4
ad
ac
ak
af
2
a
d

样例输出

4
1

题目来源

HLY

 

怪叔叔改编的题~ 嘿嘿

 

又是一道字典树水题~~  

 

题目地址:

http://218.194.91.48/acmhome/problemdetail.do?&method=showdetail&id=1308

 

只需在建立字典树的时候,每一次到达节点,使节点计数器num++

 

但这样还是会错哟~~ 因为它问的是不同单词的个数,而同一个单词可能包含有某 子串 很多遍~~

 

因此,需要特判一下,建树时,每个num++的节点,需要判断是否同一个单词,如果是,则不重复执行num++

 

具体看代码~~

 

 

#include<iostream>
#include<cstdio>

using namespace std;

char str[30];
int s[30];

struct Point{
	int num,n;
	Point *next[52];
};
Point *root;

void init_(Point *x){
	x->num=0;
	x->n=-1;
	for(int i=0;i<52;i++) x->next[i]=0;
}
void deal(){
	for(int i=0;str[i];i++)
		if(str[i]>='a') s[i]=str[i]-'a';
		else s[i]=str[i]-39;
}
void add(int n){
	Point *p,*now;
	int i,j;
	deal();
	for(i=0;str[i];i++){
		now=root;
		for(j=i;str[j];j++){
			if(!now->next[s[j]]){
				p=new Point;
				init_(p);
				now->next[s[j]]=p;
			}
			now=now->next[s[j]];
			if(now->n!=n){
				now->num++;
				now->n=n;
			}
		}
	}
}
int qry(){
	Point *p,*now=root;
	int i;
	deal();
	for(i=0;str[i];i++){
		if(!now->next[s[i]]) break;
		now=now->next[s[i]];
	}
	if(!str[i]) 
		return now->num;
	else return 0;
}

int main(){
	int n;
	while(~scanf("%d",&n)){
		root=new Point;
		init_(root);
		while(n--){
			scanf("%s",str);
			add(n);
		}
		scanf("%d",&n);
		while(n--){
			scanf("%s",str);
			printf("%d\n",qry());
		}
	}
	return 0;
}

抱歉!评论已关闭.