题目中的描述就很最近公共祖先,再说其实这个题并不难,就是麻烦点(代码其实可以化简的),我写的判定比较多。
方法;求出两者的最近公共祖先lca,在求出两者到lca的距离
分析:给出a和b,如果LCA(a,b) == a或者b,那他们肯定是窒息的,是父子,爷孙之类的关系。
如果LCA(a,b)> a 和 b,假如说a的辈分高(使用深度代表辈分),且disa = 1,那么他们是叔叔,侄子之类的关系
再者就是堂姐堂弟的关系了,代码里解释的比较详细,代码如下:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; #define N 32767 struct Node { int l,r,pa,deep; } node[N+10]; void dfs(int x,int d) { if(x > N) return; node[x].l = x*2+1; node[x].r = x*2+2; node[x].deep = d; if(x==0) node[x].pa = x; else if(x%2==0) node[x].pa = x/2-1; else node[x].pa = x/2; dfs(node[x].l,d+1); dfs(node[x].r,d+1); } int LCA(int a,int b) { while(node[a].deep > node[b].deep) { a = node[a].pa; } while(node[b].deep > node[a].deep) { b = node[b].pa; } while(a != b) { a = node[a].pa; b = node[b].pa; } return a; } int main() { // freopen("A.in.cpp","r",stdin); dfs(0,1);///预处理每一个节点的父亲和深度 int a,b,lca,disa,disb; string tmp; char gender; while(~scanf("%d %d %c",&a,&b,&gender)) { if(a==-1 && b==-1) break; lca = LCA(a,b);///求出lca和距离 disa = node[a].deep - node[lca].deep; disb = node[b].deep - node[lca].deep; // printf("LCA(%d,%d) = %d\n",a,b,lca); // printf("lca - deep = %d\n",node[lca].deep); // printf("disa = %d disb = %d\n",disa,disb); if(a == b) printf("self\n"); else if(disa == disb && disa == 1)///姐弟关系 { if(gender == ‘F‘) printf("sister\n"); else printf("brother\n"); } else if(lca == a)///直系关系 { if(gender == ‘F‘) tmp = "daughter"; else tmp = "son"; if(disb == 1) cout<<tmp<<endl; else if(disb == 2) cout<<"grand"<<tmp<<endl; else if(disb == 3) cout<<"great-grand"<<tmp<<endl; else if(disb == 4) cout<<"great-great-grand"<<tmp<<endl; else printf("kin\n"); } else if(lca == b) { if(gender == ‘F‘) tmp = "mother"; else tmp = "father"; if(disa == 1) cout<<tmp<<endl; else if(disa == 2) cout<<"grand"<<tmp<<endl; else if(disa == 3) cout<<"great-grand"<<tmp<<endl; else if(disa == 4) cout<<"great-great-grand"<<tmp<<endl; else printf("kin\n"); } else if(node[a].pa == lca && node[a].deep < node[b].deep)///叔侄关系 { if(gender == ‘F‘) tmp = "niece"; else tmp = "nephew"; if(disb == 2) cout<<tmp<<endl; else if(disb == 3) cout<<"grand"<<tmp<<endl; else if(disb == 4) cout<<"great-grand"<<tmp<<endl; else if(disb == 5) cout<<"great-great-grand"<<tmp<<endl; else printf("kin\n"); } else if(node[b].pa == lca && node[a].deep > node[b].deep) { if(gender == ‘F‘) tmp = "aunt"; else tmp = "uncle"; if(disa == 2) cout<<tmp<<endl; else if(disa == 3) cout<<"grand"<<tmp<<endl; else if(disa == 4) cout<<"great-grand"<<tmp<<endl; else if(disa == 5) cout<<"great-great-grand"<<tmp<<endl; else printf("kin\n"); } else if(disa >= 2 && disb >= 2)///堂姐堂弟 { tmp = "cousin"; int Max = max(disa,disb); int Min = min(disa,disb); int cha = Max - Min;///这个差帮助我们判定后代 if(Min <= 4 && cha <= 3) { if(Min == 2) cout<<"1st "<<tmp; else if(Min == 3) cout<<"2nd "<<tmp; else if(Min == 4) cout<<"3rd "<<tmp; if(cha == 0) cout<<endl; else if(cha == 1) cout<<" once removed"<<endl; else if(cha == 2) cout<<" twice removed"<<endl; else if(cha == 3) cout<<" thrice removed"<<endl; } else cout<<"kin"<<endl; } else cout<<"kin"<<endl; } return 0; }
时间: 2024-11-05 09:14:00