ZJU 09 複試上機 第五題

第五題: 找出直系親屬。如果ABC的父母親,則ABCparentCABchild,如果ABC的(外)祖父,祖母,則ABCgrandparentCABgrandchild,如果ABC的(外)曾祖父,曾祖母,則ABCgreat-grandparentCABgreat-grandchild,之後再多一輩,則在關係上加一個great-

輸入:n0<=n<=26)表示n個親屬關係,形式爲ABC,表示A的父母親分別是BC,如果A的父母親信息不全,則用-代替,例如A-Cm(。。。)代表測試用例數,形式AB。輸出:AB的關係,如AB的直系親屬,按上述要求輸出關係,如果AB沒有關係,輸出-。當n0時結束。

 

Input

3 2

ABC

CDE

EFG

FA

BE

0 0

 

Output:

great-grandparent

這道題目重點之一在於信息的組織,因爲任意一個節點有兩個雙親,而兒女個數不是確定的,因此沒法使用一般的樹結構來組織信息,圖結構不能反映層次關係 更加不好處理,可以採用靜態鏈表的方案 發現這種方案在這種小型算法程序中比較好用 位置指針便於使用 也避免繁瑣的指針細節  接下來就是沿着這個節點位置向祖先路徑上遍歷,訪問時檢查是否匹配,一旦查找到就立刻結束,使用tag作爲深度展開的入口檢查條件,因爲只能訪問祖先,調換順序 再訪問一次,如果還未找到不要忽略了二者可能是兄弟結點(這裏題目不是很清,要注意陷阱),最後的分支是輸出二者沒有任何關係

總結

重點在於三點

1.選擇合適的組織信息方案;

2,開始時記得把所有的結點標記爲空(-1),以便作爲遞歸終止標識//注意開始犯的錯誤,只初始到n

3,熟悉搜索框架,進行必要的剪枝

//一開始犯了一個錯誤,n只是關係的數目,而不是結點編號的最大值,所以調試的時候出現異常,因爲所有後面未能初始化的結點都被默認初始化爲0,即爲A的孩子

#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
int tag,level;

int convert(char c)
{
 return c-'A';
}

struct node
{
 int father,mother;//直接轉換爲編號,不用字母
};

node record[30];

void search(int from,int to,int count)
{
 if(record[from].mother==to||record[from].father==to)
 {
  level=count;
  tag=0;//標記,結束探查 減枝;
  return;
 }
 if(record[from].mother!=-1&&tag)search(record[from].mother,to,count+1);
 if(record[from].father!=-1&&tag)search(record[from].father,to,count+1);
}

 

int main()
{
 int n,m;
 while(cin>>n>>m&&n)
 {
  int i;
  for(i=0;i<26;i++)//因爲不可能窮極所有的父母信息,所以初始化爲未知是最方便的以後作爲遍歷終止條件
   record[i].mother=record[i].father=-1;//沒說編號規則,這裏改成26更好一點
   
  string input;
  for(i=0;i<n;i++)
  {
   cin>>input;
   int number;
   number=convert(input[0]);
   if(input[1]!='-')record[number].father=convert(input[1]);
   if(input[2]!='-')record[number].mother=convert(input[2]);
  }
  while(m--)
  {
   char from,to;
   cin>>from>>to;
   tag=1;
   search(convert(from),convert(to),0);
   if(!tag)//找到,to爲from的祖先
   {
    if(level==0)cout<<"child"<<endl;
    else if(level==1)cout<<"grandchild"<<endl;
    else
    {
     while(level>1)cout<<"great-",level--;
     cout<<"grandchild"<<endl;
    }
    continue;
   }
   tag=1;
   search(convert(to),convert(from),0);
   if(!tag)//找到,from爲to的祖先
   {
    if(level==0)cout<<"parent"<<endl;
    else if(level==1)cout<<"grandparent"<<endl;
    else
    {
     while(level>1)cout<<"great-",level--;
     cout<<"grandparent"<<endl;
    }
    continue;
   }
   //注意要考慮二者是不是兄弟,這裏就不考慮單親相同了
   int v1=convert(from);
   int v2=convert(to);
   if((record[v1].mother==record[v2].mother)&&(record[v1].father==record[v2].father))
   {
    cout<<"brother"<<endl;
    continue;
   }
   cout<<"-"<<endl;//unknow relationship

  }
 }
 return 0;
}

發佈了39 篇原創文章 · 獲贊 2 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章