浙江大学机试 找出直系亲属 Easy *并查集
基本思想:
其实用二叉树更简单一点,但是个人认为题目有可能不太严谨,会出现多棵树情况,用二叉树一样的还是要判断节点是否在一棵树上,没啥必要;
关键点:
无;
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<set>
#include<cmath>
using namespace std;
const int maxn = 26;
int father[maxn];
void init() {
for (int i = 0; i < maxn; i++) {
father[i] = i;
}
}
int findfather(int n) {
while (father[n] != n)
n = father[n];
return n;
}
void Union(int a, int b) {
father[b] = a;
}
int find_level(int n) {
int cnt = 0;
while (father[n] != n) {
cnt++;
n = father[n];
}
return cnt;
}
bool is_stright(int a, int b) {
int t1 = a;
int t2 = b;
while (t1 != father[t1]) {
t1 = father[t1];
if (b == t1)
return true;
}
while (t2 != father[t2]) {
t2 = father[t2];
if (a == t2)
return true;
}
return false;
}
void charge(int a, int b) {
int aa = find_level(a);
int bb = find_level(b);
int cnt = aa - bb;
if (cnt > 0) {
//爷爷辈;
if (cnt == 1) {
cout << "parent" << endl;
}
else {
string s = "grandparent";
while (cnt != 2) {
cnt--;
s = "great-" + s;
}
cout << s << endl;
}
}
else {
cnt = abs(cnt);
//孙子辈;
if (cnt == 1) {
cout << "child" << endl;
}
else {
string s = "grandchild";
while (cnt != 2) {
cnt--;
s = "great-" + s;
}
cout << s << endl;
}
}
}
int main() {
int m, n;
string s;
while (cin >> n >> m) {
init();
for (int i = 0; i < n; i++) {
cin >> s;
for (int i = 1; i < 3; i++) {
if (s[i] != '-')
Union(s[0] - 'A', s[i] - 'A');
}
}
for (int i = 0; i < m; i++) {
cin >> s;
if (!is_stright(s[0] - 'A', s[1] - 'A')) {
cout << '-' << endl;
continue;
}
charge(s[0] - 'A', s[1] - 'A');
}
}
}

浙公网安备 33010602011771号