Codeforces 514C Watto and Mechanism Trie树 + dfs
2015-02-25 22:44
375 查看
题目大意:
现在需要找的字符串S的T的关系为两者长度相同且刚好有1处字符不同
就是对于给定的n个字符串(n <= 3*10^5), 对于接下来输入的m次字符串询问(m <= 3*10^5), 每一次询问的字符串如果在给定的n个字符串中存在满足上述关系的串输出YES, 否则输出NO
大致思路:
就是将n个字符串插入Trie树暴搜一下就过了....
给出一点可能错的样例吧:
Input:
3 2
a
b
c
bb
a
b
Output:
NO
YES
YES
代码如下:
Result : Accepted Memory : 255196 KB Time : 358 ms
/*
* Author: Gatevin
* Created Time: 2015/2/25 13:24:49
* File Name: poi~.cpp
*/
#include<iostream>
#include<sstream>
#include<fstream>
#include<vector>
#include<list>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#include<ctime>
#include<iomanip>
using namespace std;
const double eps(1e-8);
typedef long long lint;
int n, m, N;
char in[800000];
const int max_node = 20000000;//10000000 Runtime Error果断改20000000了...
bool flag;
struct Trie
{
int next[max_node][3];
bool end[max_node];
int L, root;
int newnode()
{
for(int i = 0; i < 3; i++)
next[L][i] = -1;
end[L++] = 0;
return L - 1;
}
void init()
{
L = 0;
root = newnode();
}
void insert(char *s)
{
int now = root;
for(; *s; s++)
{
if(next[now][*s - 'a'] == -1)
next[now][*s - 'a'] = newnode();
now = next[now][*s - 'a'];
}
end[now] = 1;
}
void dfs(int len, bool used, int now)
{
if(len == N && used && end[now]) flag = true;
if(flag) return;
if(len >= N) return;
if(used)
{
if(next[now][in[len] - 'a'] != -1)
dfs(len + 1, used, next[now][in[len] - 'a']);
}
else
{
for(int i = 0; i < 3; i++)
if(len + 1 == N && next[now][i] != -1 && i != in[len] - 'a' && end[next[now][i]])
flag = true;
for(int i = 0; i < 3; i++)
if(i != in[len] - 'a' && next[now][i] != -1)
dfs(len + 1, true, next[now][i]);
if(next[now][in[len] - 'a'] != -1)
dfs(len + 1, false, next[now][in[len] - 'a']);
}
}
};
Trie trie;
int main()
{
scanf("%d %d", &n, &m);
trie.init();
while(n--)
{
scanf("%s", in);
trie.insert(in);
}
while(m--)
{
scanf("%s", in);
N = strlen(in);
flag = false;
trie.dfs(0, false, 0);
if(flag) printf("YES\n");
else printf("NO\n");
}
return 0;
}
现在需要找的字符串S的T的关系为两者长度相同且刚好有1处字符不同
就是对于给定的n个字符串(n <= 3*10^5), 对于接下来输入的m次字符串询问(m <= 3*10^5), 每一次询问的字符串如果在给定的n个字符串中存在满足上述关系的串输出YES, 否则输出NO
大致思路:
就是将n个字符串插入Trie树暴搜一下就过了....
给出一点可能错的样例吧:
Input:
3 2
a
b
c
bb
a
b
Output:
NO
YES
YES
代码如下:
Result : Accepted Memory : 255196 KB Time : 358 ms
/*
* Author: Gatevin
* Created Time: 2015/2/25 13:24:49
* File Name: poi~.cpp
*/
#include<iostream>
#include<sstream>
#include<fstream>
#include<vector>
#include<list>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#include<ctime>
#include<iomanip>
using namespace std;
const double eps(1e-8);
typedef long long lint;
int n, m, N;
char in[800000];
const int max_node = 20000000;//10000000 Runtime Error果断改20000000了...
bool flag;
struct Trie
{
int next[max_node][3];
bool end[max_node];
int L, root;
int newnode()
{
for(int i = 0; i < 3; i++)
next[L][i] = -1;
end[L++] = 0;
return L - 1;
}
void init()
{
L = 0;
root = newnode();
}
void insert(char *s)
{
int now = root;
for(; *s; s++)
{
if(next[now][*s - 'a'] == -1)
next[now][*s - 'a'] = newnode();
now = next[now][*s - 'a'];
}
end[now] = 1;
}
void dfs(int len, bool used, int now)
{
if(len == N && used && end[now]) flag = true;
if(flag) return;
if(len >= N) return;
if(used)
{
if(next[now][in[len] - 'a'] != -1)
dfs(len + 1, used, next[now][in[len] - 'a']);
}
else
{
for(int i = 0; i < 3; i++)
if(len + 1 == N && next[now][i] != -1 && i != in[len] - 'a' && end[next[now][i]])
flag = true;
for(int i = 0; i < 3; i++)
if(i != in[len] - 'a' && next[now][i] != -1)
dfs(len + 1, true, next[now][i]);
if(next[now][in[len] - 'a'] != -1)
dfs(len + 1, false, next[now][in[len] - 'a']);
}
}
};
Trie trie;
int main()
{
scanf("%d %d", &n, &m);
trie.init();
while(n--)
{
scanf("%s", in);
trie.insert(in);
}
while(m--)
{
scanf("%s", in);
N = strlen(in);
flag = false;
trie.dfs(0, false, 0);
if(flag) printf("YES\n");
else printf("NO\n");
}
return 0;
}
相关文章推荐
- Codeforces 282E. Sausage Maximization【trie树(非指针版)】
- 【Codeforces 750 D New Year and Fireworks】+ DFS
- Codeforces 29C Mail Stamps 【离散化 + DFS】
- Codeforces 706D Trie树/multiset
- CodeForces 396C 树状数组 + DFS
- Trie树 + DFS - CSU 1457 Boggle
- Codeforces 665E. Beautiful Subarrays (trie树)
- Codeforces 665E Beautiful Subarrays (Trie树)
- codeforces 706D trie树 或 muliset
- Codeforces 706D-Vasiliy's Multiset(Trie树)
- 字符串哈希 Trie树 Watto and Mechanism : CodeForces - 514C
- 【codeforces 731 C Socks】+ DFS
- Codeforces 615C Running Track(DP + Trie树)
- [Codeforces 557E] Ann and Half-Palindrome (Trie树+子串排序)
- CodeForces 396C 树状数组 + DFS
- Trie树 + DFS - CSU 1457 Boggle
- Codeforces 633C Spy Syndrome 2(DP + Trie树)
- codeforces 706D D. Vasiliy's Multiset(trie树)
- Sausage Maximization - CodeForces 282 E Trie树
- Codeforces 633C Spy Syndrome 2 | Trie树裸题