您的位置:首页 > 其它

Family Name List (HDU 4409)

2012-12-08 00:20 417 查看
周赛的题目,废了好大劲才看懂的,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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: