アイスランドチーム1による2018年のワールドカップ、:1つの強力なアルゼンチンとのレベルと彼女の有名なを作りました。おせっかいは、アイスランド人の後ろの名前を見つける「緩い」(息子を)持っているように見える次のように、その後、友人の科学があります。
息子はSSON、娘プラスsdottirを追加した場合のアイスランド人は、古代のバイキング父方の姓システム、子供の父親の姓同じ名前の接尾辞に従ってください。少ないアイスランドの人口ため、近親交配を避けるために、以前に地元の交換は2人の先祖かどうかを1つのアプリとの接触のいくつかの世代をチェックします。この質問は、このアプリケーションの機能を実現するように要求されます。
入力フォーマット:
まず、入力最初の行の正の整数N(1 <N≤105)、地域住民の数。次いで、N行は、各列の形式で名前を与えられる名 姓(带性别后缀)
2つの文字列を超えない20の小文字の英字によって。ヴァイキングの子孫が名サフィックスによって彼らの性別を決定することができ、他の人は、姓の後に追加されm
、表現の男性f
、女性のために。トピックは、ヴァイキングの家族が男性になっている指定されたそれぞれの人の起源を保証します。
そして、彼の党は、正の整数M、クエリの数を示します。続いて、M行、フォーマット指定された名前の各列一組:名1 姓1 名2 姓2
。注意:これは姓
接尾辞ではありません。せいぜい20の小文字の英文字によって4つの文字列。
トピックには二人が同じ名前ではないがあることを確認してください。
出力フォーマット:
各クエリについて、結果が1行で次の情報を示しています。
- 2つの異性、ノー共通の祖先少ない5つの世代の場合、出力
Yes
; - 2つの異性場合が、(第五世代含まない)五代内で、共通の祖先、出力を有します
No
。 - 2人は同性愛、その後、出力された場合
Whatever
。 - 人がリストにない場合は、出力
NA
。
いわゆる「5世代内の共通の祖先は」当事者の曽祖父の年功序列よりも高くなければならない2つの共通の祖先(もしあれば)を意味しません。
サンプル入力:
15
chris smithm
adam smithm
bob adamsson
jack chrissson
bill chrissson
mike jacksson
steve billsson
tim mikesson
april mikesdottir
eric stevesson
tracy timsdottir
james ericsson
patrick jacksson
robin patricksson
will robinsson
6
tracy tim james eric
will robin tracy tim
april mike steve bill
bob adam eric steve
tracy tim tracy tim
x man april mikes
出力例:
Yes
No
No
Whatever
Whatever
NA
コードは以下の通りであります:
import java.util.ArrayList;
import java.util.Scanner;
class Person {
String firstName;
String sex;
public Person(String firstName, String sex) {
super();
this.firstName = firstName;
this.sex = sex;
}
}
public class Main {
static int[] tree;
static ArrayList<Integer> family = new ArrayList<Integer>();
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
ArrayList<String> allName = new ArrayList<String>();
Person[] per = new Person[N];
tree = new int[N]; //家庭树,建立并查集
sc.nextLine();
//构建家庭树
for(int i=0;i<N;i++) {
String Name = sc.nextLine();
String[] name = Name.split(" ");
//男后裔
if(name[1].indexOf("sson")!=-1) {
name[1] = name[1].replace("sson", "");
per[i] = new Person(name[0], "m");
}
//女后裔
else if(name[1].indexOf("sdottir")!=-1) {
name[1] = name[1].replace("sdottir", "");
per[i] = new Person(name[0], "f");
}
//男祖先
else if(name[1].charAt(name[1].length()-1)=='m') {
per[i] = new Person(name[0], "m");
}
//女祖先
else if(name[1].charAt(name[1].length()-1)=='f') {
per[i] = new Person(name[0], "f");
}
allName.add(name[0]); //存储名字
//根据其父亲是否存在建立并查集队列
int index = allName.indexOf(name[1]);
if(index == -1)
tree[i] = i;
else
tree[i] = index;
}
//查询
N = sc.nextInt();
sc.nextLine();
for(int i=0;i<N;i++) {
String Name = sc.nextLine();
String[] name = Name.split(" ");
int index1 = allName.indexOf(name[0]);
int index2 = allName.indexOf(name[2]);
if(index1!=-1 && index2!=-1) {
if(per[index1].sex.equals(per[index2].sex)) {
System.out.println("Whatever");
}
else {
if(find(index1)!=find(index2) || judge(index1, index2)) {
System.out.println("Yes");
}
else {
System.out.println("No");
}
}
}
else {
System.out.println("NA");
}
}
}
//并查集查找
public static int find(int i) {
if(tree[i]!=i) {
return find(tree[i]);
}
else
return i;
}
public static boolean judge(int index1, int index2) {
int ret = 1;
while (index1 != tree[index1] && index2 != tree[index2]) {
index1 = tree[index1];
index2 = tree[index2];
++ret;
if (ret == 5) return true; //不在五代以内
if (index1 == index2) return false; //五代以内存在共同祖先
}
return false;
}
}
することができ、私はそれが間違ってまし始まりは、ビットを書き互いに素セットされている、最も重要な部分を検討し、その後、構築し、チェックアウトを設定する方法であるアルゴリズムを考え、しばらく考えた後、共通の祖先例5つの世代の中にはありません問題、そして反応し、コードは完全なポイントを取得していない、テストポイントのうち最後の2回は、フォローアップを改善する方法を見つけることができます。