啊啊好不容易才在贴吧上翻到这两张图……
家谱(gen)
题目描述
守矢神社的早苗对于本家族血统总是记不住,现在给出充足的父子关系,请你编写程序找到她
家族中某个人的最早的祖先。
输入
多行组成,首先是一系列有关父子关系的描述,其中每一组父子关系由二行组成,用#name 的
形式描写一组父子关系中的父亲的名字,用+name 的形式描写一组父子关系中的儿子的名字;
接下来用?name 的形式表示要求该人的最早的祖先;最后用单独的一个$表示文件结束。规定
每个人的名字都有且只有6 个字符,而且首字母大写,且没有任意两个人的名字相同。最多可
能有1000 组父子关系,总人数最多可能达到50000 人,家谱中的记载不超过30 代。
输出
求出每一个要找祖先的人的祖先,格式:本人的名字+一个空格+祖先的名字+回车。
我的题解能得60分(
1 /* 2 写代码人:zx 3 批注人:zx 4 指导老师:gg 5 我真菜,真的/ 6 */ 7 #include<cstdio> 8 #include<cstring> 9 using namespace std; 10 char mz[50005][8]; 11 int fa[50005]; 12 int getf(int v) 13 { 14 if(fa[v] == 0) return v; 15 else{ 16 return fa[v] = getf(fa[v]); 17 } 18 } 19 int main() 20 { 21 freopen("gen.in","r",stdin); 22 freopen("gen.out","w",stdout); 23 char c; 24 int t = 0; 25 char s1[7],s2[7],s[7]; 26 bool bb = true; 27 bool bb2; 28 while(1){ 29 if(bb) gets(s); 30 bb = true; 31 if(s[0] == '$') break; 32 if(s[0] == '#'){ 33 s[0] = '0'; 34 strcpy(s1,s); 35 if(t == 0){ 36 t++; 37 strcpy(mz[t],s1); 38 } 39 while(1){ 40 gets(s2); 41 if(s2[0] == '+'){ 42 s2[0] = '0'; 43 t++; 44 strcpy(mz[t],s2); 45 bb2 = true; 46 s1[0] = '0'; 47 for(int i = 1;i < t;i++){ 48 if(strcmp(mz[i],s1) == 0){ 49 fa[t] = i; 50 bb2 = false; 51 break; 52 } 53 } 54 if(bb2){ 55 fa[t] = t + 1; 56 t++; 57 strcpy(mz[t],s1); 58 } 59 } 60 else{ 61 bb = false; 62 strcpy(s,s2); 63 break; 64 } 65 } 66 67 } 68 if(s[0] == '?'){ 69 s[0] = '0'; 70 for(int i = 1;i <= t;i++){ 71 if(strcmp(mz[i],s) == 0){ 72 for(int j = 1;j <= 6;j++) printf("%c",s[j]); 73 printf(" "); 74 for(int j = 1;j <= 6;j++) printf("%c",mz[getf(i)][j]); 75 printf(" "); 76 break; 77 } 78 } 79 } 80 } 81 return 0; 82 }