Description
Input
Output
Sample Input
START from fiwo hello difh mars riwosf earth fnnvk like fiiwj END START difh, i'm fiwo riwosf. i fiiwj fnnvk! END
Sample Output
hello, i'm from mars. i like earth!
Hint
Huge input, scanf is recommended.
输入数据量比较大,其实也就是最基础的trie树啦,不过!这题如果是你想象中辣么简单就大错特错啦,,,,,,,,,5555,硬生生被坑在了数据上(此题如果句末有标点符号,才能对应输出!!!!!!!否则根本没输出555555555555,就因为这个wa了十几次,还有为这题苦思冥想觉得自己写的很对结果就是wa的骚年吗?!谨记我的教训啊555555555)
#include <iostream> #include<stdio.h> #include<string.h> using namespace std; const int NODE = 1e7+10,CH = 26; int ch[NODE][CH],sz,val[NODE]; char a1[1000001][15],a2[15]; /** ch[u][c]: 节点u指向的c儿子的边 val[u]: 节点u的值 sz: trie树的size */ int idx(char c) {return c-'a';} int node() { /** 新建(初始化)节点 **/ memset(ch[sz],0,sizeof(ch[sz])); ///将所有儿子置为空 val[sz]=0; return sz++; } void init() { sz=0; ///trie树根节点为下标0的节点 node(); } void insert(char *s,int v) { int u=0; for(;*s;s++) { int c=idx(*s); ///如果节点不存在 新建节点 并把值赋给当前节点的c儿子边 if(!ch[u][c]) ch[u][c]=node(); ///继续移动 u=ch[u][c]; } ///在末尾节点记录信息 val[u]=v; } int find(char *s) { int u=0; for(;*s;s++) { int c=idx(*s); ///如果u节点没有c儿子 结束 if(!ch[u][c]) return 0; u=ch[u][c]; } return val[u]; } int zm(char x) { if(x>='a'&&x<='z') return 1; return 0; } int main() { char start[7],chu[15]; scanf("%s",start); int o=0; while(~scanf("%s",a1[o])) { if(strcmp(a1[o],"END")==0) break; scanf("%s",a2); if(o==0) strcpy(chu,a2); insert(a2,o++); } char b1[3005]; scanf("%s",start); getchar(); while(gets(b1)) { if(strcmp(b1,"END")==0) break; int i,l=strlen(b1),flag=0,k=0; char t[15]; for(i=0;i<l;i++) if(flag==0&&zm(b1[i])==1) t[k++]=b1[i],flag=1; else if(flag==1&&zm(b1[i])==1) t[k++]=b1[i]; else if(flag==1&&zm(b1[i])==0) { t[k]='\0'; if(strcmp(chu,t)==0) { printf("%s",a1[0]);memset(t,0,sizeof(t)); k=0,flag=0; printf("%c",b1[i]);continue; } if(find(t)==0) printf("%s",t); else printf("%s",a1[find(t)]); memset(t,0,sizeof(t)); k=0,flag=0; printf("%c",b1[i]); } else if(flag==0&&zm(b1[i])==0) printf("%c",b1[i]); printf("\n"); } return 0; }