题目1035:找出直系亲属

题目1035:找出直系亲属
题目描述:
    如果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.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Scanner;
import java.util.Stack;


public class Main {
	   
	   public static void main(String[] args) throws IOException {
		    
		      Scanner cin = new Scanner(new BufferedInputStream(System.in)) ;
		      PrintWriter cout = new PrintWriter(System.out) ; 
		      
		      int n , m ;
		      while(true){
		    	    n = cin.nextInt() ;
		    	    m = cin.nextInt() ;
		    	    if(n == 0 && m == 0) break  ;
		    	    new Task().solve(n , m , cin , cout);  
		      }
		      
			  cout.flush() ; 
	   }
	   

}


class  Task{
	
	   Person[] person = new Person[26] ;
	   Task() {
		    for(int i = 0 ; i < 26 ; i++)
		    	person[i] = new Person() ;
	   }
	   
	   void  solve(int n , int m , Scanner  cin , PrintWriter cout){
		     while(n-- > 0){
		    	  String  s = cin.next() ;
		    	  int son =   s.charAt(0) - 'A' ;
		    	  if(s.charAt(1) != '-') person[son].father = s.charAt(1) - 'A' ;
		    	  if(s.charAt(2) != '-') person[son].mother = s.charAt(2) - 'A' ;
		     }
		     while(m-- > 0){
		    	  String s = cin.next() ;
		    	  int u = s.charAt(0) - 'A' ;
		    	  int v = s.charAt(1) - 'A' ;
		    	  
		    	  int utov = dfs(u, v) ;
		    	  int vtou = dfs(v, u) ;
		    	  if(utov > 0) cout.println(getNameUtoV(utov)) ;
		    	  else if(vtou > 0) cout.println(getNameVtoU(vtou)) ;
		    	  else cout.println("-") ;
		     }
		    // cout.flush() ;
	   }
	   
	   int dfs(int u , int v){
		   if(v == u) return 0 ;
		   if(person[u].father != null){
			     int dep = dfs(person[u].father ,  v ) ;
			     if(dep != -1) return dep + 1 ;
		   }
		   
		   if(person[u].mother != null){
			     int dep = dfs(person[u].mother ,  v ) ;
			     if(dep != -1) return dep + 1 ;
		   }
		   
		   return -1 ;	   
	   }
	   
	   String  getNameVtoU(int dep){
		       if(dep == 1) return "parent" ;
		       else if(dep == 2) return "grandparent" ;
		       else{
		    	    String name = "" ;
		    	    for(int i = 3 ; i <= dep ; i++) name += "great-" ;
		    	    name += "grandparent" ;
		    	    return name ;
		       }
	   }
	   
	   String  getNameUtoV(int dep){
	       if(dep == 1) return "child" ;
	       else if(dep == 2) return "grandchild" ;
	       else{
	    	    String name = "" ;
	    	    for(int i = 3 ; i <= dep ; i++) name += "great-" ;
	    	    name += "grandchild" ;
	    	    return name ;
	       }
       }
	   
}

class  Person{
	   Integer  father ;
	   Integer  mother ;
	   public   Person() {
		        father = mother = null  ; 
	   }
}






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值