UVA - 12219(唯一性标记法的应用)
来源:互联网 发布:java用for循环打印菱形 编辑:程序博客网 时间:2024/05/22 03:47
用唯一性标记法,在递归建树时,给每个数分配唯一识别编号记为id ,用map来记录(name,lson_id, rson_id)是否被标记过。
方法,很简单,但是有一点就是建树的时候遍历字符串,一定要做到o(n) ,否则超时。
下面为自己的,版本,简言之,先建树,唯一标记每棵子树,(因为序号分配是从下往上不同于题目要求,有重新转化为题目要求的编号)
#include <set>#include <map>#include <vector>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <cmath>using namespace std;typedef long long LL;const int maxn = 1005555;struct node{ string c; int l,r; node(string c="0",int l=0,int r=0): c(c),l(l),r(r){} bool operator <(const node& rhs)const{ if(c!=rhs.c){ return c < rhs.c; } else{ return l<rhs.l||(l==rhs.l&&r<rhs.r); } }};map<node,int> vis;vector<node> idcache;int ID(node c){ if(vis.count(c)) return vis[c]; idcache.push_back(c); return vis[c]=idcache.size();}typedef struct tree* pointer;struct tree{ int id; string s; pointer Left,Right; tree(string s="0",pointer x=NULL,pointer y=NULL): s(s),Left(x),Right(y){}};pointer root;char str[maxn],src[maxn],*p;int build(pointer& u){ u = new tree(); int i,cnt=0; u->s.clear(); while(islower(*p)){ u->s.push_back(*p); p++; } if(*p!='('){ return u->id=ID(node(u->s,0,0)); } p++; int num1 = build(u->Left); p++; int num2 = build(u->Right); p++; return u->id=ID(node(u->s,num1,num2) );}void dfs(pointer u){ if(u->Left==NULL){ if(vis.count(node(u->s,0,0))) printf("%d",vis[node(u->s,0,0)]); else { ID(node(u->s,0,0)); cout<<u->s; } return ; } if(vis.count(node(u->s,u->Left->id,u->Right->id))) printf("%d",vis[node(u->s,u->Left->id,u->Right->id)]); else{ cout<<u->s; ID(node(u->s,u->Left->id,u->Right->id)); printf("("); dfs(u->Left); printf(","); dfs(u->Right); printf(")"); }}int main(){ int T; scanf("%d",&T); while(T--){ scanf("%s",str); vis.clear(); idcache.clear(); p= str; build(root); vis.clear(); idcache.clear(); dfs(root); printf("\n"); } return 0;}但是,可以用数组式建树预分配编号。若已经被访问取消预分配。
#include <set>#include <map>#include <vector>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <cmath>using namespace std;typedef long long LL;const int maxn = 100000;char str[maxn*5],src[maxn],*p;struct node{ string s; int left,right,ha; bool operator < (const node& rhs)const{ if(ha!=rhs.ha) return ha<rhs.ha; else if(left!=rhs.left) return left<rhs.left; else return right<rhs.right; }}a[maxn];int cn=0,fu=1;map<node,int> vis;int build(){ int id = cn++; node& u=a[id]; u.s.clear(); u.ha = 0; u.left=u.right = -1; while(islower(*p)){ char c = *p; u.s.push_back(c); u.ha=u.ha*27+(c)-'a'+1; p++; } if(*p=='('){ p++; u.left=build(); p++; u.right=build(); p++; } if(vis.count(u)){ cn--; return vis[u]; } return vis[u] = id;}int T,V[maxn*6];void dfs(int id){ if(V[id] == T) printf("%d",id+1); else { V[id] = T; printf("%s",a[id].s.c_str()); if(a[id].left!=-1){ printf("("); dfs(a[id].left); printf(","); dfs(a[id].right); printf(")"); } }}int main(){ int ca; scanf("%d",&ca); for(T=1;T<=ca;T++){ scanf("%s",str); cn=0; vis.clear(); p = str; build(); dfs(0); printf("\n"); } return 0;}
0 0
- UVA - 12219(唯一性标记法的应用)
- iOS 中UUID唯一标记的使用
- 关于唯一设备标记的相关链接
- uva 11572 唯一的雪花 Unique Snowflakes
- 【uva 11572】 唯一的雪花 滑动窗口
- uva 11572 Unique Snowflakes (唯一的雪花)
- HTML音频标记的应用
- Requirejs高级应用(五):模块的唯一性鉴别
- MySql数据唯一标记方法
- uva 1220 树的最大独立集和唯一性的判断
- 主键,外键,索引,唯一索引的应用
- java生成唯一序列号,UUID的应用
- 程序的唯一性
- 应用程序的唯一性
- 滚动字幕标记marquee的应用
- 一个”flag“标记的小应用
- UVA 10780 (唯一分解)
- uva 11572 唯一的雪花(滑动窗口)
- poj3070
- 二十个经典管理学定律
- poj 2041 Unreliable Message 字符串处理
- 内存性能的优化
- 【总结】- markdown标记语言使用手册
- UVA - 12219(唯一性标记法的应用)
- android开发-0前言
- 对于c++我原来没有发现过的问题!!!
- 也谈Volley的二次封装
- 【技巧】- Xcode常用快捷键
- 指针变量与函数指针形参
- 在ZEMAX和MATLAB之间通信
- android开发-1准备安装操作系统
- C# winform 窗口属性详解