hihoCoder 1260 String Problem I

26 篇文章 0 订阅
13 篇文章 0 订阅

#1260 : String Problem I

时间限制: 10000ms
单点时限: 1000ms
内存限制: 256MB

描述

我们有一个字符串集合S,其中有N个两两不同的字符串。

还有M个询问,每个询问给出一个字符串w,求有多少S中的字符串可以由w添加恰好一个字母得到。

字母可以添加在包括开头结尾在内的任意位置,比如在"abc"中添加"x",就可能得到"xabc", "axbc", "abxc", "abcx".这4种串。

输入

第一行两个数N和M,表示集合S中字符串的数量和询问的数量。

接下来N行,其中第i行给出S中第i个字符串。

接下来M行,其中第i行给出第i个询问串。

所有字符串只由小写字母构成。

数据范围:

N,M<=10000。

S中字符串长度和<=100000。

所有询问中字符串长度和<=100000。

输出

对每个询问输出一个数表示答案。

样例输入
3 3
tourist
petr
rng
toosimple
rg
ptr
样例输出
0
1
1
解题思路:Trie+DFS,提供几组数据
3 3
aba bab aab
ab ba aa
3 2 1
3 1
aab aba abb
ab 
3
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <set>
#include <map>
#include <list>
#include <queue>
#include <stack>
#include <deque>
#include <vector>
#include <bitset>
#include <cmath>
#include <utility>
#define Maxn 100005
#define Maxm 1000005
#define lowbit(x) x&(-x)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define PI acos(-1.0)
#define make_pair MP
#define LL long long 
#define Inf (1LL<<62)
#define inf 0x3f3f3f3f
#define re freopen("in.txt","r",stdin)
#define wr freopen("out.txt","w",stdout)
using namespace std;
struct TrieNode
{
    int cnt;
    TrieNode *next[26];
    TrieNode()
    {
		cnt=0;
        memset(next,0,sizeof(next));
    }
};
TrieNode *root=NULL;
void CreatTree(char *s,int len)
{
    TrieNode *p=root;
    TrieNode *temp;
    for(int i=0;i<len;i++)
    {
        if(p->next[s[i]-'a']==NULL)
        {
            temp=new TrieNode;
            p->next[s[i]-'a']=temp;
        }
        p=p->next[s[i]-'a'];
		p->cnt++;
    }
}
int ans;
void Search(TrieNode *node,char *s,int pos,int len,int flag)
{
	if(pos==len)
	{
		ans+=node->cnt;
		return ;
	}
    for(int i=0;i<26;i++)
	{
		if(node->next[i]!=NULL)
		{
			if(s[pos]=='a'+i)
				Search(node->next[i],s,pos+1,len,flag);
			else if(flag==1)
				Search(node->next[i],s,pos,len,flag-1);
		}
	}
	return ;
}
void Delete(TrieNode *node)
{
    for(int i=0;i<26;i++)
    {
        if(node->next[i])
            Delete(node->next[i]);
        delete node->next[i];
        node->next[i]=0;
    }
}
int main()
{
	int m,n,index;
	bool visit[100005];
	map<string,bool> vis;
	root=new TrieNode;
	char str1[10005],str2[10005];
	while(~scanf("%d %d",&m,&n))
	{
		getchar();
		memset(visit,false,sizeof(visit));
		for(int i=0;i<m;i++)
		{
			scanf("%s",str1);
			visit[strlen(str1)]=true;
			CreatTree(str1,strlen(str1));
		}
		for(int i=0;i<n;i++)
		{
			ans=0;
			scanf("%s",str2);
			vis.clear();
			if(!visit[strlen(str2)+1])
			{
				puts("0");
				continue;
			}
			int len=strlen(str2);
			Search(root,str2,0,len,1);
			printf("%d\n",ans);
		}
		Delete(root);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值