天梯题集——冰岛人(隐藏条件:考虑嫡系)

电玩女神 2022-12-24 09:56 209阅读 0赞

前文

愿天下有情人都是失散多年的兄妹 与 冰岛人 解题思路几乎是同理的,不过这里需要考虑多一个是否嫡系的关系
(卡了我好久、又来一个隐藏条件,长知识、长知识…)。
用递归实现很容易出现超时,循环果然比递归效率高。
循环与递归效率的比较

冰岛人

t1
t2
t3


解题难点

①、记录数据——映射+结构体

  1. struct node{
  2. string fa;
  3. int sex;
  4. };
  5. map <string, node> num;

第一次把映射和结构体结合起来,查询方便了许多。


②、判断 m1 与 m2 是否是嫡亲

  1. //判断 s1 是否为 s2 的嫡系
  2. bool judge1(string s1, string s2){
  3. for(string A=s1; !A.empty(); A=num[A].fa)
  4. if(A==s2) return false;
  5. return true;
  6. }

③、m1 与 m2 五代以内无有公共祖先

  1. //s1与s2五代以内无有公共祖先
  2. bool judge2(string s1, string s2){
  3. int i=1;
  4. string A, B;
  5. for(A=s1; !A.empty()&&i<=5; i++){
  6. int j=1;
  7. for(B=s2; !B.empty()&&j<=5; j++){
  8. if(A==B&&(i<5||j<5))
  9. return 0;
  10. B=num[B].fa;
  11. }
  12. A=num[A].fa;
  13. }
  14. return 1;
  15. }

实现代码

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. struct node{
  4. string fa;
  5. int sex;
  6. };
  7. map <string, node> num;
  8. //判断 s1 是否为 s2 的嫡系
  9. bool judge1(string s1, string s2){
  10. for(string A=s1; !A.empty(); A=num[A].fa)
  11. if(A==s2) return false;
  12. return true;
  13. }
  14. //s1与s2五代以内无有公共祖先
  15. bool judge2(string s1, string s2){
  16. int i=1;
  17. string A, B;
  18. for(A=s1; !A.empty()&&i<=5; i++){
  19. int j=1;
  20. for(B=s2; !B.empty()&&j<=5; j++){
  21. if(A==B&&(i<5||j<5))
  22. return 0;
  23. B=num[B].fa;
  24. }
  25. A=num[A].fa;
  26. }
  27. return 1;
  28. }
  29. int main(){
  30. int n, k;
  31. scanf("%d", &n);
  32. for(int i=0; i<n; i++){
  33. string m, x;
  34. cin>>m>>x;
  35. //判断性别
  36. switch(x[x.size()-1]){
  37. case 'm': num[m].sex = 'm';
  38. break;
  39. case 'f': num[m].sex = 'f';
  40. break;
  41. case 'n': num[m].fa = x.substr(0, x.size()-4);
  42. num[m].sex = 'm';
  43. break;
  44. case 'r': num[m].fa = x.substr(0, x.size()-7);
  45. num[m].sex = 'f';
  46. break;
  47. }
  48. }
  49. cin>>k;
  50. for(int i=0; i<k; i++){
  51. string m1, x1, m2, x2;
  52. cin>>m1>>x1>>m2>>x2;
  53. if(num.find(m1)==num.end()||num.find(m2)==num.end())
  54. cout<<"NA\n";
  55. else if(num[m1].sex==num[m2].sex)
  56. cout<<"Whatever\n";
  57. else{
  58. if(judge1(m1, m2)&&judge1(m2, m1)&&judge2(m1, m2))
  59. cout<<"Yes\n";
  60. else
  61. cout<<"No\n";
  62. }
  63. }
  64. return 0;
  65. }

总结

看了网上一些代码,并没有将全部情况都考虑到,但判题时能够通过全部样例,就很神奇。
比赛期间尽管提交,能混到分的话,就很妙…

发表评论

表情:
评论列表 (有 0 条评论,209人围观)

还没有评论,来说两句吧...

相关阅读