trie 树习题
1.hdu 1305?Immediate Decodability
算法思路:trie樹模板,在插入的同時(shí)進(jìn)行統(tǒng)計(jì)是否存在,有想法,得動(dòng)腦子,當(dāng)腦子空洞的時(shí)候,注意要有邏輯判斷能力,大膽想,大膽假設(shè)
現(xiàn)在假定兩個(gè)字符串A,B。 A的長度小于B。分兩種情況,
當(dāng)B先輸入時(shí)(即長的先輸入),途經(jīng)的結(jié)點(diǎn)的flag如果為1,即如果有小于B的單詞,便為前綴。
當(dāng)A先輸入時(shí)(即短的先輸入),當(dāng)建立到A的最后一個(gè)字符時(shí), 如果該結(jié)點(diǎn)已存在,那么證明,已有一個(gè)以該字符為前綴的字符已經(jīng)輸入。
#include<bits/stdc++.h> using namespace std; struct node{int a[2];int end_; }trie[2000]; char s[15]; int tot=1;int res=1; void insert(char s[]) {int p=0;int len=strlen(s);for(int i=0;i<len;i++){int t=s[i]-'0';if(trie[p].a[t]==0)trie[p].a[t]=tot++;p=trie[p].a[t];if(trie[p].end_==1) res=0;}trie[p].end_=1; } void init(){for(int i=0;i<=2000;i++){trie[i].a[0]=0,trie[i].a[1]=0,trie[i].end_=0;}tot=1;res=1; } int main() {int num=1;while(cin>>s){init();insert(s);while(cin>>s){if(s[0]=='9') break;else insert(s);}if(res==1) printf("Set %d is immediately decodable\n",num);else printf("Set %d is not immediately decodable\n",num);num++;}return 0; } View Code2.hdu 1251 統(tǒng)計(jì)難題
算法思路:trie樹模板,走過一個(gè)節(jié)點(diǎn),數(shù)量+1;
#include<bits/stdc++.h> using namespace std; struct node{int a[26],num; }trie[10000000]; char s[10];int tot=1; void insert(char s[]) {int len=strlen(s);int p=0;for(int i=0;i<len;i++){int t=s[i]-'a';if(trie[p].a[t]==0)trie[p].a[t]=tot++;p=trie[p].a[t];trie[p].num++;} } int find(char s[]) {int p=0;int len=strlen(s);for(int i=0;i<len;i++){int t=s[i]-'a';p=trie[p].a[t];if(p==0) return 0;}return trie[p].num; } int main() {int tmp=1;while(cin.getline(s,20)){if(strlen(s)==0) {tmp=0;continue;}if(tmp==1) insert(s);else{int ans=find(s);cout<<ans<<endl;}}return 0; } View Code3.hdu 1671 phone list
算法思路:同1
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=1e5+5; /*struct node{int a[10],end; }trie[maxn];*/ int trie[maxn][10],cmp[maxn]; int res=1,tot=1;char s[20]; void insert(char s[],int k,int n) {int len=strlen(s);int p=0;for(int i=0;i<len;i++){int t=s[i]-'0';if(trie[p][t]==0)trie[p][t]=tot++;p=trie[p][t];if(cmp[p]==1) res=0;}cmp[p]=1;/*if(k==n){for(int i=0;i<=9;i++){if(trie[p][i]!=0){res=0;break;}}}*/for(int i=0;i<10;i++)if(trie[p][i]!=0) res=0; } void init() {for(int i=0;i<maxn;i++){for(int j=0;j<=9;j++){trie[i][j]=0;}cmp[i]=0;}tot=1,res=1; } int main() {int t;cin>>t;while(t--){init();int n;cin>>n;for(int i=1;i<=n;i++){cin>>s;if(res) insert(s,i,n);else continue;}if(res==1) printf("YES\n");else printf("NO\n");}return 0; } View Code4.hdu 1075??What Are You Talking About
算法思路:火星文替換,trie樹模板,增加火星文的空間,如果是結(jié)尾時(shí),則將火星文給他,另外這題的gets用法和字符串指針的用法很奇妙
gets會(huì)將換行符變?yōu)樽址Y(jié)束符,對(duì)字符串的處理能力弱弱弱,另外注意%s時(shí)需用getchar吞掉換行符!!
#include<bits/stdc++.h> using namespace std; struct node{int a[26];char chh[20];int end; }trie[1000000];int tot=1; void insert(char *ch1, char *ch2)//ch1 mars,ch2 e a {int p=0;for(int i=0;ch1[i]!='\0';i++){int t=ch1[i]-'a';if(trie[p].a[t]==0)trie[p].a[t]=tot++;p=trie[p].a[t];}trie[p].end=1;strcpy(trie[p].chh,ch2); } void query(char *ch1) {int p=0;for(int i=0;ch1[i]!='\0';i++){int t=ch1[i]-'a';p=trie[p].a[t];if(p==0){printf("%s",ch1);return;}}if(trie[p].end) {printf("%s",trie[p].chh);return;}else {printf("%s",ch1);return;} } int main() {char ch1[3010],ch2[3010];scanf("%s",&ch1);while(~scanf("%s",&ch2)){if(strcmp(ch2,"END")!=0){scanf("%s",&ch1);insert(ch1,ch2);}else break;}scanf("%s",&ch1);//cout<<ch1; getchar();while(gets(ch1)!=NULL){//cout<<ch1;if(strcmp(ch1,"END")==0){ break;}else{//cout<<"233";int len=strlen(ch1);int tmp=0;char cc;ch1[len]='\n';ch1[len+1]='\0';//gets會(huì)將換行符變成字符串結(jié)束符 for(int i=0;i<=len;i++){if(!islower(ch1[i])){cc=ch1[i];ch1[i]='\0';//標(biāo)記為結(jié)尾 query(ch1+tmp);tmp=i+1;printf("%c",cc);}}}}return 0; } View Code5.hdu 3460??Ancient Printer
算法思路:
一開始沒有明白題意,看了好久,才明白,原來它是將一個(gè)單詞打印出來后再在打印機(jī)里面刪除字母,也就是說,如果單詞前綴相同,則只需刪除單詞不相同的部分,再插入下一個(gè)單詞不相同的部分。這樣的話,可以用字典樹,要是單詞前綴相同,則在字典樹上只有一個(gè)結(jié)點(diǎn),那么,要是將最長的那個(gè)單詞也刪除了,則是對(duì)字典樹上的結(jié)點(diǎn)插入一次再刪除一次,還要輸出n次,也就是2*numnode+n;但是最長的那個(gè)單詞len不需要?jiǎng)h除,則是2*numnode+n-len; #include<bits/stdc++.h> using namespace std; struct node{int a[26],end; }trie[500010]; void init(){for(int i=0;i<500010;i++){for(int j=0;j<26;j++){trie[i].a[j]=0;}trie[i].end=0;} } int tot=1; void insert(char *s) {int p=0;int len=strlen(s);for(int i=0;i<len;i++){int t=s[i]-'a';if(trie[p].a[t]==0)trie[p].a[t]=tot++;p=trie[p].a[t];}trie[p].end=1; } int main() {int n;char s[50];while(cin>>n){init();tot=1;int maxnum=0;for(int i=1;i<=n;i++){scanf("%s",&s);insert(s);int tmp=strlen(s);maxnum=max(tmp,maxnum);}cout<<(tot-1)*2-maxnum+n<<endl; }return 0; } View Code6.hdu 2072 單詞數(shù)
算法思路:其實(shí)用字符串處理+trie或者set都可以,重點(diǎn)是字符串的處理。。。。。sscanf,gets的用法,指針不斷移動(dòng)
#include<bits/stdc++.h> using namespace std; set<string>aa;//set中第一次加上string int main()//語言無非就是字母數(shù)字符號(hào)了 {while(1){char tmp[1000];char s[10000];cin.getline(s,10000);//讓我復(fù)習(xí)了getline的用法 int nums=strlen(s);if(s[0]=='#') break;int num=0;while(s[num]==' ') num++;//此法可以用來判斷非字母的任何作為間隔的東西 while(num<nums)//字符串的分割 {sscanf(s+num,"%s",tmp);int len1=strlen(tmp);//cout<<len1<<' '<<tmp<<endl;aa.insert(tmp);//char到string的自動(dòng)轉(zhuǎn)換 num+=len1;//很不明白題目為什莫要挖這莫多坑 num++;//溜了溜了 while(s[num]==' ') num++;//消除間隔 ,防止錯(cuò)位 }cout<<aa.size()<<endl;aa.clear();}return 0; } View Code?
轉(zhuǎn)載于:https://www.cnblogs.com/vainglory/p/8505928.html
總結(jié)
- 上一篇: 4.1邮箱的全选,全不选,反选
- 下一篇: spring boot mybatis没