周赛的题目,废了好大劲才看懂的,STL不够熟悉,需要近一步训练啊
点击打开链接http://blog.sina.com.cn/s/blog_79aa283901018w01.html 转载地址
#include <cstdio>
#include <map>
#include <set>
#include <string>
#include <queue>
#include <stack>
#include <iostream>
using namespace std;
int main()
{
int n;
while(scanf("%d", &n) != EOF && n)
{
map<string, set<string> > son; //孩子节点
map<string, string> father; //父亲节点
map<int, string> sta; //存放各个辈数最近的人名
map<string, int> cnt; //存放每个人名的辈数
char name[64];
scanf("%s", name);
sta[0] = string(name); //转换成string
cnt[name] = 0; //设祖先的辈分为0
for(int i = 1; i < n; ++i)
{
scanf("%s", name);
int gen = 0;
while(name[gen] == '.') //计算辈分
++ gen;
cnt[name+gen] = gen; //存储辈分
father[name+gen] = sta[gen-1]; //存放父亲节点
sta[gen] = name+gen; //以辈分为下标存放人名,为下一个子节点使用
son[father[name+gen]].insert(name+gen); //把此节点作为父亲的子节点存储
}
int K;
scanf("%d", &K);
for(int i = 0; i < K; ++i)
{
char order[4];
scanf("%s", order);
if(order[0] == 'L')
{
stack<string> stk;
stk.push(sta[0]);
while(stk.size())
{
string now = stk.top();
for(int j = 0; j < cnt[now]; ++j)
putchar('.'); //像终端输出一个字符
cout << now << endl;
stk.pop();
for(set<string>::reverse_iterator it = son[now].rbegin(); it != son[now].rend(); ++it)
{
stk.push(*it);
}
}
}
if(order[0] == 'b')
{
scanf("%s", name);
if(cnt[name] == 0) printf("1\n");
else printf("%d\n", son[father[name]].size());
}
if(order[0] == 'c')
{
string name1, name2;
cin >> name1 >> name2;
name1 = father[name1];
name2 = father[name2];
while(cnt[name1] != cnt[name2])
{
if(cnt[name1] > cnt[name2])
name1 = father[name1];
else name2 = father[name2];
}
while(name1 != name2)
{
name1 = father[name1];
name2 = father[name2];
}
cout << name1 << endl;
}
}
}
return 0;
}