这题是一个基础的treap题,就是把树建好然后中序遍历输出一下就好,但是我根本不知道treap是神马东西,查了一下发现treap就是一种同时满足二叉排序树和堆的性质的数据结构,也叫笛卡尔树。每个节点有两个值,一个代表关键字,一个代表优先级,主要操作有左旋和右旋,以保证treap满足其性质。这道题为了便于处理先把数据读入然后按关键字排序,然后每次都插入在前一个插入节点的右儿子处,如果不满足性质则进行右旋,只到处在正确的位置再插入下一个元素。通过这个题也见识到了C语言强大的scanf函数的功能,%*[ ]代表跳过[ ]中的元素不读入只到遇到不是括号中元素的数据,%[^/]代表读入字符串遇到‘/’停止,但不读入。
#include <iostream>
#include <cstdio>
#include <string.h>
#include <algorithm>
using namespace std;
struct Node
{
char str[105];
int value,ls,rs,pa;
Node()
{
value=pa=ls=rs=0;
memset(str,0,sizeof(str));
}
}treap[50005];
bool operator < (const Node a,const Node b)
{
return strcmp(a.str,b.str)<0;
}
void insert(int i)
{
int j=i-1;
while(treap[j].value<treap[i].value)
j=treap[j].pa;
treap[i].ls=treap[j].rs;
treap[j].rs=i;
treap[i].pa=j;
}
void dfs(int i) //中序遍历
{
if(i)
{
printf("(");
dfs(treap[i].ls);
printf("%s/%d",treap[i].str,treap[i].value);
dfs(treap[i].rs);
printf(")");
}
}
int main()
{
int n;
while(scanf("%d",&n),n)
{
memset(treap,0,sizeof(treap));
for(int i=1;i<=n;i++)
{
scanf("%*[ ]%[^/]/%d",treap[i].str,&treap[i].value); //刚知道C语言也能用正则表达式……
}
sort(treap+1,treap+n+1);
treap[0].value=10000000;
for(int i=1;i<=n;i++)
{
insert(i);
}
dfs(treap[0].rs);
printf("\n");
}
}
by zh