题目1035:找出直系亲属 树

本文介绍了一种通过递归查找直系亲属关系的算法,该算法能够处理复杂的家族关系,并能准确判断任意两人之间的直系亲属关系。文章详细解释了输入格式、处理流程和输出结果,提供了一个完整的Java实现案例。

题目1035:找出直系亲属

时间限制:1 秒

内存限制:32 兆

特殊判题:

提交:2931

解决:1145

题目描述:
    如果A,B是C的父母亲,则A,B是C的parent,C是A,B的child,如果A,B是C的(外)祖父,祖母,则A,B是C的grandparent,C是A,B的grandchild,如果A,B是C的(外)曾祖父,曾祖母,则A,B是C的great-grandparent,C是A,B的great-grandchild,之后再多一辈,则在关系上加一个great-。
输入:
    输入包含多组测试用例,每组用例首先包含2个整数n(0<=n<=26)和m(0<m<50), 分别表示有n个亲属关系和m个问题, 然后接下来是n行的形式如ABC的字符串,表示A的父母亲分别是B和C,如果A的父母亲信息不全,则用-代替,例如A-C,再然后是m行形式如FA的字符串,表示询问F和A的关系。
    当n和m为0时结束输入。
输出:
    如果询问的2个人是直系亲属,请按题目描述输出2者的关系,如果没有直系关系,请输出-。
    具体含义和输出格式参见样例.
样例输入:
3 2
ABC
CDE
EFG
FA
BE
0 0
样例输出:
great-grandparent
-
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;


public class Main {
    public static void main(String[] args) {
	    new Task().solve() ;  	
	}
}

class Task{
	InputReader in = new InputReader(System.in) ;
	PrintWriter out = new PrintWriter(System.out) ;
	
	class Node{
		Node father , mother ;
		char val ;
		Node(char val , Node father , Node mother){
			this.val = val ;
			this.father = father ;
			this.mother = mother ;
		}
	}

	int dfs(Node first , Node second){
        if(first == second) return 0 ;
        if(first.father != null){
        	int high = dfs(first.father , second) ;
        	if(high != -1) return high + 1 ;
        }
        if(first.mother != null){
        	int high = dfs(first.mother , second) ;
        	if(high != -1) return high + 1 ;
        }	
        return -1 ;
	}
	
	void solve(){
		int n , m ;
		while(true){
			n = in.nextInt() ;
			m = in.nextInt() ;
			if(n == 0 && m == 0) break ; 
			Map<Character , Node> mapper = new HashMap<Character, Task.Node>() ;
			while(n-- > 0){
				String args = in.next() ;
				Node father = mapper.get(args.charAt(1)) ;
				if(father == null){
					father = new Node(args.charAt(1) , null , null) ;
					mapper.put(args.charAt(1), father) ;
				}
				Node mother = mapper.get(args.charAt(2)) ;
				if(mother == null){
					mother = new Node(args.charAt(2) , null , null) ;
					mapper.put(args.charAt(2), mother) ;
				}
				Node node = mapper.get(args.charAt(0)) ;
				if(node == null){
					node = new Node(args.charAt(0) , father, mother) ;
					mapper.put(args.charAt(0), node) ;
				}
				else{
					node.father = father ;
					node.mother = mother ;
				}
		    }
			while(m-- > 0){
				String args = in.next() ;
				if(args.charAt(0) == args.charAt(1)){
					out.println("-") ;
					continue ;
				}
				Node first = mapper.get(args.charAt(0)) ;
				Node second = mapper.get(args.charAt(1)) ;
				if(first == null || second == null){
					out.println("-") ;
					continue ;
				}
				int cnt = dfs(first, second) ;
				if(cnt != -1){
					if(cnt == 1) out.println("child") ;
					else if(cnt == 2) out.println("grandchild") ;
					else{
						for(int i = 1 ; i <= cnt - 2 ; i++) out.print("great-") ;
						out.println("grandchild") ;
					}
				}
				else{
					cnt = dfs(second , first) ;
					if(cnt != -1){
						if(cnt == 1) out.println("parent") ;
						else if(cnt == 2) out.println("grandparent") ;
						else{
							for(int i = 1 ; i <= cnt - 2 ; i++) out.print("great-") ;
							out.println("grandparent") ;
						}
					}
					else out.println("-") ;
				}
			}
		}
		out.flush();
	}
}


class InputReader {  
    public BufferedReader reader;  
    public StringTokenizer tokenizer;  
  
    public InputReader(InputStream stream) {  
        reader = new BufferedReader(new InputStreamReader(stream), 32768);  
        tokenizer = new StringTokenizer("");  
    }  
  
    private void eat(String s) {  
        tokenizer = new StringTokenizer(s);  
    }  
  
    public String nextLine() {  
        try {  
            return reader.readLine();  
        } catch (Exception e) {  
            return null;  
        }  
    }  
  
    public boolean hasNext() {  
        while (!tokenizer.hasMoreTokens()) {  
            String s = nextLine();  
            if (s == null)  
                return false;  
            eat(s);  
        }  
        return true;  
    }  
  
    public String next() {  
        hasNext();  
        return tokenizer.nextToken();  
    }  
  
    public int nextInt() {  
        return Integer.parseInt(next());  
    }  
  
    public long nextLong() {  
        return Long.parseLong(next());  
    }  
  
    public double nextDouble() {  
        return Double.parseDouble(next());  
    }  
  
    public BigInteger nextBigInteger() {  
        return new BigInteger(next());  
    }  
  
}  




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值