家谱处理

题目:

人类学研究对于家族很感兴趣,于是研究人员搜集了一些家族的家谱进行研究。实验中,使用计算机处理家谱。为了实现这个目的,研究人员将家谱转换为文本文件。下面为家谱文本文件的实例:

John
  Robert
    Frank
    Andrew
  Nancy
    David

家谱文本文件中,每一行包含一个人的名字。第一行中的名字是这个家族最早的祖先。家谱仅包含最早祖先的后代,而他们的丈夫或妻子不出现在家谱中。每个人的子女比父母多缩进2个空格。以上述家谱文本文件为例,John这个家族最早的祖先,他有两个子女RobertNancyRobert有两个子女FrankAndrewNancy只有一个子女David

在实验中,研究人员还收集了家庭文件,并提取了家谱中有关两个人关系的陈述语句。下面为家谱中关系的陈述语句实例:

John is the parent of Robert
Robert is a sibling of Nancy
David is a descendant of Robert

研究人员需要判断每个陈述语句是真还是假,请编写程序帮助研究人员判断。

输入格式:

输入首先给出2个正整数N(2≤N≤100)和M(≤100),其中N为家谱中名字的数量,M为家谱中陈述语句的数量,输入的每行不超过70个字符。

名字的字符串由不超过10个英文字母组成。在家谱中的第一行给出的名字前没有缩进空格。家谱中的其他名字至少缩进2个空格,即他们是家谱中最早祖先(第一行给出的名字)的后代,且如果家谱中一个名字前缩进k个空格,则下一行中名字至多缩进k+2个空格。

在一个家谱中同样的名字不会出现两次,且家谱中没有出现的名字不会出现在陈述语句中。每句陈述语句格式如下,其中XY为家谱中的不同名字:

X is a child of Y
X is the parent of Y
X is a sibling of Y
X is a descendant of Y
X is an ancestor of Y

输出格式:

对于测试用例中的每句陈述语句,在一行中输出True,如果陈述为真,或False,如果陈述为假。

输入样例:

6 5
John
  Robert
    Frank
    Andrew
  Nancy
    David
Robert is a child of John
Robert is an ancestor of Andrew
Robert is a sibling of Nancy
Nancy is the parent of Frank
John is a descendant of Andrew

输出样例:

True
True
True
False
False

分析:注意Sibling指的是亲兄弟姐妹,父子关系合而为一,后代与祖先关系合二为一,一个map记录父子关系,一个map记录每一层当前父亲。不用建树,代码要少很多。

代码:

#include<bits/stdc++.h>
using namespace std;
const int N = 1e4+10;
int n,m;
map<string,string> fa;
map<int,string> name;

int main() {
    cin>>n>>m;
    getchar();///!!!
    for(int i=1;i<=n;i++) {
        string s;
        getline(cin,s);///!
        int cnt=count(s.begin(),s.end(),' ');///!
        string ss=s.substr(cnt);///!
        name[cnt/2]=ss;
        if(i==1) fa[ss]="no";
        else fa[ss]=name[cnt/2-1];
    }
    for(int i=1;i<=m;i++) {
        string a,b,c,d,e,f;
        cin>>a>>b>>c>>d>>e>>f;
        if(d[0]=='p'||d[0]=='c') {
            if(d[0]=='p') swap(a,f);
            if(fa[a]==f) cout<<"True"<<endl;
            else cout<<"False"<<endl;
        }else if(d[0]=='a'||d[0]=='d') {
            if(d[0]=='a') swap(a,f);
            while(fa[a]!="no"&&fa[a]!=f) a=fa[a];
            if(fa[a]!="no") cout<<"True"<<endl;
            else cout<<"False"<<endl;
        }else if(d[0]=='s') {
            if(fa[a]==fa[f]) cout<<"True"<<endl;
            else cout<<"False"<<endl;
        }
    }
    return 0;
}

 

家谱软件是应海峡姓氏研究之约开发的族谱管理软件。 该软件是最新开发和上市的族谱管理软件,经过专业人士的指导和专业团队的开发,是目前国内性价比很高的专业族谱管理软件。 该软件具有管理大家族的能力,扩充能力在千万、亿级别,适合修全国统谱。可以谱修全国各个姓氏的族谱,对管理姓氏无限制。在同一软件上可以管理本家族和其他家族的资料,例可以管理外亲等家族的同步资料。 经过近三年的专业团队开发已经具有完善的族谱管理功能,可以帮助专业的谱修人士完成建谱、调谱、出谱等复杂的工作。该软件已经经过专业人士的测试,指导,能够完成大部分人的修谱需求。 该软件采用最先进的开发技术,采用国外最强大的单机版数据库技术,具有无限扩充能力和功能完善能力,该数据库支持的是上亿级别的数据处理。其技术为微软的开发平台支持,是其他族谱软件所无法比拟的平台和技术支撑。采用微软的visual studio开发技术,该技术是微软的最先进开发技术,从微软创办至今一直完善的一个技术支撑。 单机版本,数据库为单一文件,不是其他族谱软件的一堆数据文件。该数据库文件可以自己备份管理,可以拷贝到其他机器硬盘等来备份。 该程序可以脱网来使用,不需要上网,完全属于自己的软件,放心,安全,不受任何网络和第三方的控制。 该软件是目前市场上唯一直接对树操作的族谱管理软件,可以在树世系图上任意增加族人,选择某一族人后可以增加兄弟或子女。增加族人人数无限制。使用鼠标右键操作,符合大家的操作习惯。可以任意修改族人在树上的位置,方便在填错父亲的情况下将其修改回原来在树上的位置。在树上的位置可以整个分支改挂到另外一个分支,调整族人分支很方便。适合先建族人后修改父亲等需求。 该软件一改以往修谱软件的特点,增加了输出word文档的功能,方便在打印前对出谱资料的二次修改,具有很强的可修改性。另外,可以将族人图形资料输出到word文档,和族人资料一起一并打印。可以打印输出族人的图形等可见信息。 可以在数据库内保存家族和族人的语音、视频、扫描资料等重要资料,由于保存在数据库内,所以具有保密性。家谱资料在数据库内可以删除、查看,方便整个家族资料的管理和完备性。 可以将世系树的结构输出到文本文档,对于家族的分支结构在树上得到很好的诠释。由于文本文档不具有格式性, 所以可以输出无限大的世系图,可以将整个家族的世系图完整输出 。 具有输出部分世系图分支的功能,可以分段输出世系图,便于将世系图分段保存和管理。配合整个世系图和分段世系图,对于某一分支可以了解自家分支的世系全貌。 可以管理多个配偶信息,配偶信息的输出是附加在族人后面,对于家庭的完整性得到很好的体现。配偶信息资料全,可以了解配偶在自家的排行、兄弟姐妹等情况。 自定义家谱输出格式,方便输出古代的五代格式。五代输出按大排行方式输出,符合大家的排行习惯。 族人输出按照大排行的顺序输出,例子老大的儿子输出要排在老二儿子的前边, 老大的孙子输出也要排在老二孙子的前边,以此类推。 可以管理家族的历史事件,历史人物,可以任意增加历史事件和历史人物,来阐述家族曾经出得辉煌。增加的人物和事件无限制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值