Codeforces 514C. Watto and Mechanism解題報告(字典樹)
阿新 • • 發佈:2018-10-04
test names cin 單詞 turn void can include 傳送門
傳送門
題意:給你一個字典和一些詢問,問你對於每個詢問的字符串必須更改一個字符,能否得到字典中的某一個單詞。
思路:先構造一顆字典樹,然後搜一遍就行了,要註意strlen不能每次都用,常數很大!
#include<bits/stdc++.h> #define rep(i,k,n) for(int i=k;i<=n;i++) using namespace std; const int maxn=300005,maxm=600005; int tree[maxm][5],en[maxm]; int n,m,e; char s[maxm]; bool flag; bool siz[maxm]; int lenth; void add_edge(char c[]) { int len=(int)strlen(c); int root=0; rep(i,0,len-1) { if(!tree[root][c[i]-'a']) tree[root][c[i]-'a']=++e; root=tree[root][c[i]-'a']; } en[root]=1; siz[(int)strlen(c)]=1; } void dfs(int root,int x,int pos,int cn) { if(flag)return; //cout<<char(x+'a')<<" "<<pos<<endl; if(pos>=lenth) { return; } int cnn=cn; if(pos==lenth-1 && en[root]) { //cout<<char(x+'a')<<" "<<pos<<endl; if((x==s[pos]-'a' && cnn==1) || (x!=s[pos]-'a' && cnn==0)) flag=1; return; } if(pos!=-1) { if(s[pos]-'a'!=x) { cnn++; if(cnn>=2) return; } } int i=0; if(tree[root][i] && (cnn==0 || (cnn==1 && s[pos+1]-'a'==i))) { dfs(tree[root][i],i,pos+1,cnn); if(flag) return; } i=1; if(tree[root][i] && (cnn==0 || (cnn==1 && s[pos+1]-'a'==i))) { dfs(tree[root][i],i,pos+1,cnn); if(flag) return; } i=2; if(tree[root][i] && (cnn==0 || (cnn==1 && s[pos+1]-'a'==i))) { dfs(tree[root][i],i,pos+1,cnn); if(flag) return; } } int main() { scanf("%d%d",&n,&m); if(n==1 && m==1) { string s1,s2; cin>>s1>>s2; if(s1.size()!=s2.size()) { puts("NO"); return 0; } int cnt=0; rep(i,0,s1.size()-1) { if(s1[i]!=s2[i]) { cnt++; } if(cnt>=2) { flag=1; break; } } if(flag || cnt==0) puts("NO"); else puts("YES"); return 0; } rep(i,1,n) { char c[maxm]; scanf("%s",c); add_edge(c); } //cout<<en[0]<<endl; rep(i,1,m) { scanf("%s",s); lenth=(int)strlen(s); flag=0; if(siz[lenth]==0) { puts("NO"); continue; } dfs(0,0,-1,0); if(flag) puts("YES"); else puts("NO"); } return 0; }
Codeforces 514C. Watto and Mechanism解題報告(字典樹)