题目描述:
给出n个串(总长<=30000),求是否有一个无限长的串,使得不包含任何一个给出串。
题解:
建trie图,然后搜索。
搜索时如果这个点搜过以后无法return true,那么我们可以标记这个点。
只要再次搜到这个点直接return false
代码:
#include<queue> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define N 30050 int n,tot; char ch[N]; struct Trie { int ch[2],fl,w; }tr[N]; void trie_pic() { queue<int>q; for(int i=0;i<=1;i++) if(tr[0].ch[i]) q.push(tr[0].ch[i]); while(!q.empty()) { int u = q.front(); q.pop(); for(int i=0;i<=1;i++) { int &v = tr[u].ch[i]; if(!v) { v=tr[tr[u].fl].ch[i]; continue; } tr[v].fl = tr[tr[u].fl].ch[i]; tr[v].w|=tr[tr[v].fl].w; q.push(v); } } } bool vis[N],ot[N]; bool dfs(int u) { if(ot[u])return 0; if(vis[u])return 1; vis[u]=1; for(int i=0;i<=1;i++) { int to = tr[u].ch[i]; if(tr[to].w)continue; if(dfs(to))return 1; } vis[u]=0; ot[u]=1; return 0; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%s",ch+1); int u = 0,len = strlen(ch+1); for(int j=1;j<=len;j++) { int c = ch[j]-'0'; if(!tr[u].ch[c])tr[u].ch[c]=++tot; u=tr[u].ch[c]; } tr[u].w|=1; } trie_pic(); bool ans = dfs(0); printf(ans?"TAK\n":"NIE\n"); return 0; }