HDU 3724 Encoded Barcodes (2010 Asia Tianjin Regional Contest )
2015-11-06 21:53
423 查看
【题目链接】http://acm.hdu.edu.cn/showproblem.php?pid=3724
【解题报告】
trie树基础题。建立静态trie树,然后查找即可。有两个要点。
这道题目我MLE&RE了十几发。开始我不加思考的算出最多会有30*1e5个节点,所以数组直接开超内存了(根据trie树的特点,一定会有大量单词覆盖相同节点,如果不是特意卡内存显然不需要开这么大…),改完之后提交又RE,误以为是空间开小了然后就纠结…最后发现,因为我在进行prefix查找的时候,是一边读入prefix一边遍历trie树,当trie树不存在这样一个prefix的时候,直接return 0,这样导致可能还有部分数据没有读入,于是就RE了….查这个错误查了好久好久,如果不犯懒老老实实写几组数据测一测应该可以避免这样额外的时间开支。
【参考代码】
【解题报告】
trie树基础题。建立静态trie树,然后查找即可。有两个要点。
1.如何确定某个前缀覆盖了多少个单词。 很简单,我们每插入一个单词的时候,在它走过的路径上所有结点权值加1,即表示当前结点被覆盖过多少次。那么我们查找前缀的时候,前缀的最后一个字母落在哪一个节点上,返回该点权值即可。 2.如何把一个barcode转化为二进制数。 对于读入的8个数,找到最大数max_num,那么和他一样在二进制数位中表示为1的那些数A[i],满足这样一个关系:fabs(max_num-A[i])/max_num<0.1.(注意为了防止某些坑点,最好加上一个eps精度控制)
这道题目我MLE&RE了十几发。开始我不加思考的算出最多会有30*1e5个节点,所以数组直接开超内存了(根据trie树的特点,一定会有大量单词覆盖相同节点,如果不是特意卡内存显然不需要开这么大…),改完之后提交又RE,误以为是空间开小了然后就纠结…最后发现,因为我在进行prefix查找的时候,是一边读入prefix一边遍历trie树,当trie树不存在这样一个prefix的时候,直接return 0,这样导致可能还有部分数据没有读入,于是就RE了….查这个错误查了好久好久,如果不犯懒老老实实写几组数据测一测应该可以避免这样额外的时间开支。
【参考代码】
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<iostream> #include<cstdio> #include<cstring> #include<vector> #include<algorithm> using namespace std; const int eps=1e-6; const int maxnode=2*1e5+50; const int bit[9]={0,128,64,32,16,8,4,2,1 }; int barcode[9]; struct TRIE{ int ch[maxnode][26]; int val[maxnode]; int sz; void clr(){ sz=1; memset(ch,0,sizeof(ch)); memset(val,0,sizeof(val)); } int idx(char c ){ return c-'a'; } int read() { float num[9]; float max_num=0; for( int j=1; j<=8; j++ ) { scanf("%f",&num[j]); if(num[j]-max_num>eps)max_num=num[j]; } for( int j=1; j<=8; j++ ) { if( fabs(num[j]-max_num)/max_num-0.1<eps )barcode[j]=1; else barcode[j]=0; } int c=0; for( int j=1; j<=8; j++ )c+=barcode[j]*bit[j]; return c; } void ins( char* S ) { int u=0,L=strlen(S); for( int i=0; i<L; i++ ) { int c=idx(S[i]); if( !ch[u][c] ) { ch[u][c]=sz++; } val[ch[u][c]]++; u=ch[u][c]; } } int find_pre( int K ) { int u=0; bool ok=true; for( int i=1; i<=K; i++ ) { int c=read()-97; if(!ch[u][c]) ok=false; u=ch[u][c]; } if(ok)return val[u]; else return 0; } }trie; int main() { int N,M,K; while(~scanf( "%d%d",&N,&M )) { trie.clr(); int ans=0; for( int i=1; i<=N; i++ ) { char name[40]; scanf("%s",name); trie.ins( name ); } for( int i=1; i<=M; i++ ) { scanf("%d",&K ); ans+=trie.find_pre( K ); } printf("%d\n",ans); } return 0; }
相关文章推荐
- MFC对话框屏幕居中
- 一个简单的使用Quartz和Oozie调度作业给大数据计算平台执行
- hdu 5525(数学题)
- ZigZag Convertion
- 典型用户和场景
- Introduction to Algorithm - Summary of Chapter 7 - Quicksort
- 蓝懿ios 技术内容和心得交流分享 11.6
- hdu 4675 GCD of Sequence(计数)
- iOS开发——高德地图调研之显示地图、定位与地理编码等
- linux shell(2)
- 使用oschina的git服务器图文流程
- 其他权限管理命令
- 理解PHP当中的cookie
- hdu 4672 Present Day, Present Time(博弈)
- 使用DrawImage函数进行拉伸绘制时出现的过度边沿现象
- Android源码分析-Alarm机制与Binder的交互
- 喜马拉雅听 手机端协议分析
- 适配器模式
- Codeforces Round #192 (Div. 1) C. Graph Reconstruction (随机化算法)
- hiho刷题日记——第六天01背包