这一题数组要开到百万级,如1000005,不然会RE。
解题思路:字典树,为了最后统计出前缀被包含的次数,需要在构造trie的时候增加一个数组记录经过每个节点的路径数。
//模板开始
#include <string>
#include <vector>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <fstream>
#include <map>
#include <set>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include<iomanip>
#include<string.h>
#define SZ(x) (int(x.size()))
using namespace std;
int toInt(string s){
istringstream sin(s);
int t;
sin>>t;
return t;
}
template<class T> string toString(T x){
ostringstream sout;
sout<<x;
return sout.str();
}
typedef long long int64;
int64 toInt64(string s){
istringstream sin(s);
int64 t;
sin>>t;
return t;
}
template<class T> T gcd(T a, T b){
if(a<0)
return gcd(-a, b);
if(b<0)
return gcd(a, -b);
return (b == 0)? a : gcd(b, a % b);
}
#define ifs cin
//模板结束(通用部分)
#define maxnode 1000005
#define sigma_size 26
#define str_len 15
int ch[maxnode][sigma_size];
int ch_count[maxnode];
int val[maxnode];
struct Trie
{
int sz;
Trie()
{
sz = 1;
memset(ch[0], 0, sizeof(ch[0]));
memset(ch_count, 0, sizeof(ch_count));
}
int idx(char c)
{
return c - 'a';
}
void insert_trie(char* s, int v)
{
int u = 0, n = strlen(s);
for(int i = 0; i < n; i++)
{
int c = idx(s[i]);
if(!ch[u][c])
{
memset(ch[sz], 0, sizeof(ch[sz]));
val[sz] = 0;
ch[u][c] = sz++;
}
u = ch[u][c];
ch_count[u]++;
}
val[u] = v;
}
int find_trie(char* s)
{
int u = 0;
int n = strlen(s);
int flag = 1;
for(int i = 0; i < n; i++)
{
int c = idx(s[i]);
if(!ch[u][c])
{
flag = 0;
break;
}
u = ch[u][c];
}
if(flag == 0)
{
return 0;
}
else
{
return ch_count[u];
}
}
};
//hdoj 1251 统计难题
int main()
{
//ifstream ifs("shuju.txt", ios::in);
char data[str_len];
Trie t1;
while(ifs.getline(data, str_len, '\n') && data[0] != '\0')
{
t1.insert_trie(data, 1);
}
while(ifs>>data && data[0] != '\0')
{
int count = t1.find_trie(data);
cout<<count<<endl;
}
return 0;
}