Family Tree(E题)

题面:

								E. Family Tree
						time limit per test: 1 second
					memory limit per test: 256 megabytes

Farmer John owns a family-run farm that has been passed down over several generations, with a herd of cows whose familial roots can similarly be traced back several generations on the same farm. By examining old records, Farmer John is curious how the cows in his current herd are related to each-other. Please help him in this endeavor!

Input
The first line of input contains N (1≤N≤100) followed by the names of two cows. Cow names are each strings of at most 10 uppercase letters (A…Z). Farmer John is curious about the relationship between the two cows on this line of input.

The next N lines each contain two cow names X and Y, indicating that X is the mother of Y.

Output
You should print one line of output indicating the relationship between the two cows specified on the first line of input (for simplicity, let’s call these two cows BESSIE and ELSIE for the examples below). Here are the different types of relationships that are possible:

You should output “SIBLINGS” if BESSIE and ELSIE have the same mother.
BESSIE might be a direct descendant of ELSIE, meaning that ELSIE is either the mother, grand-mother, great-grand-mother, great-great-grand-mother, etc., of BESSIE. If this is the case, you should print “ELSIE is the (relation) of BESSIE”, where (relation) is the appropriate relationship, for example “great-great-grand-mother”.
If ELSIE is a child of an ancestor of BESSIE (and ELSIE is not herself an ancestor or sister of BESSIE), then ELSIE is BESSIE’s aunt. You should output “ELSIE is the aunt of BESSIE” if ELSIE is a child of BESSIE’s grand-mother, “ELSIE is the great-aunt of BESSIE” if ELSIE is a child of BESSIE’s great-grand-mother, “ELSIE is the great-great-aunt of BESSIE” if ELSIE is a child of BESSIE’s great-great-grand-mother, and so on.
If BESSIE and ELSIE are related by any other means (i.e., if they share a common ancestor), they are cousins, and you should simply output “COUSINS”.
You should output “NOT RELATED” if BESSIE and ELSIE have no common ancestor, or neither is directly descended from the other.
The following diagram helps illustrate the relationships above, which are the only relationship types you need to consider.

Observe that some relationships like “niece” (daughter of sister) are not necessary since if BESSIE is the niece of ELSIE, then ELSIE is BESSIE’s aunt.
在这里插入图片描述

题目大意:

给出A,B两个人的名字,要求出他们的关系。
给出n个关系<a,b>,a是b的母亲。

离A,B的共同祖先距离相等或者不存在:

  1. 如果A,B没有共同祖先,输出: NOT RELATED。
  2. 如果A,B相同母亲,则输出: SIBLINGS。
  3. 否则(离共同祖先的距离超过或者等于2),输出:COUSINS。

离A,B的共同祖先的距离不等:
计算出A,B各自到祖先的距离,然后以长的那个作为一颗树的主干,另外一个作为分支。假设A为主干,B为分支

  1. B是A的直系。(B到树的距离为0)
  2. B是A的…aunt(B到树的距离为1)
  3. B是A的COUSINS(B到树的距离为>1)

思路:

如题目大意所描述,先用一个par[]数组来存好关系,然后各种情况分类模拟就行,主要是细节。

#include <iostream>
#include <cstdio>
#include<cstring>
using namespace std;
#define MAX 105
struct person{
	char name[12];

}p[MAX];
int n;
int k = 2;//总人数
int par[MAX];//母女关系
int vis[MAX];//标记存在A的直系的编号

inline void init()//预处理出par[]数组
{
	scanf("%d %s %s",&n,p[0].name,p[1].name);//A,B
	for(int i = 1;i<=n;i++)
		par[i] = i;
	for(int i = 0;i<n;i++)
	{
		int x = -1,y = -1;
		char a[12],a_mother[12];
		scanf("%s %s",a_mother,a);
		for(int i = 0;i<k;i++)
		{
			if(!strcmp(a_mother,p[i].name))x = i;
			if(!strcmp(a,p[i].name))y = i;
		}
		if(x == -1){
			x = k;
			strcpy(p[k++].name,a_mother);
		}
		if(y == -1){
			y = k;
			strcpy(p[k++].name,a);
		}
		par[y] = x;

	}
}
int Find(int i,int x,int deep)
{
	if(i == x)return deep;
	else if(par[i] == i)return 0;
	else
		return Find(par[i],x,deep+1);
}
int Find1(int x,int y)
{
	static int deep = 1;
	if(par[x] == y)return deep;
	else
	{
		deep++;
		return Find1(par[x],y);
	}
}
int main()
{
	init();
	int A_ancestor = 0,B_ancestor = 1,len_A = 0,len_B = 0;
	int A = 0,B = 1,len = 0;

	while(par[A_ancestor]!=A_ancestor){A_ancestor = par[A_ancestor];len_A++;}//找A的祖先
	while(par[B_ancestor]!=B_ancestor){B_ancestor = par[B_ancestor];len_B++;}//找B的祖先

	if(A_ancestor!=B_ancestor)
	{
		printf("NOT RELATED");
		return 0;
	}

	if(len_A < len_B)swap(A,B);//A < B
	A_ancestor = A;
	while(par[A_ancestor]!=A_ancestor){vis[A_ancestor] = 1;A_ancestor = par[A_ancestor];len_A++;}//找A的祖先
	vis[A_ancestor] = 1;

	int temp = B;
	while(!vis[temp]){len++;temp = par[temp];}
	B_ancestor = temp;

	if(len>1)printf("COUSINS");
	else if(len == 1)
	{
		int deep = Find1(A,B_ancestor);
		if(deep == 1)printf("SIBLINGS");
		else
		{
			//ELSIE is the aunt of BESSIE
			printf("%s is the ",p[B].name);
			while(deep > 2){printf("great-");deep--;}
			printf("aunt of %s\n",p[A].name);
		}
	}
	else
	{
		int deep = Find1(A,B_ancestor);
		if(deep == 1)printf("%s is the mother of %s",p[B].name,p[A].name);
		else if(deep == 2)printf("%s is the grand-mother of %s",p[B].name,p[A].name);
		else
		{
			printf("%s is the ",p[B].name);
			while(deep > 2){printf("great-");deep--;}
			printf("grand-mother of %s",p[A].name);
		}
	}

	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值