PTA刷題Advanced甲級——1004.Counting Leaves——Day(2)

問題描述

在這裏插入圖片描述
簡單翻譯一下題目:
1004.計算葉子個數
一個家庭的層級結構經常被表現爲一個家譜樹。你的任務是統計這些家庭成員中誰沒有孩子。

輸入
每個輸入文件包含一個測試實例。每個實例開始的一行包含N和M,N指樹中的結點個數(0<N<100),M指非葉結點的個數。然後下面有M行,每行的格式如下:
ID K ID[1] ID[2] …ID[K]
ID是一個兩位數的數字,表示一個非葉結點。K表示其孩子的數量。隨後是一個序列,序列中是該結點的孩子結點的兩位數ID。爲了簡單起見,我們把根結點的ID固定爲01。

輸出
對於每個測試實例,你應該計算從根結點開始的每一層中沒有孩子的家庭成員的個數。數字必須在一行內輸出,用空格分隔,在每行結尾不能有多餘的空格。
測試樣例表示了一個只有兩個結點的樹,01是根結點,02是它僅有的孩子。因此在根結點01層級,沒有葉節點。再下一層級,有一個葉結點。然後我們應該在一行內輸出“0 1”。

題目分析

這道題的難度不大,我們完全可以通過數組和結構體來解決,我們把結點聲明爲一個結構體類型,其數據成員包括其父結點father、是否有孩子結點Nochild以及它所在的層次level(最終我們會根據層次來輸出有多少葉子節點)。
然後我們每行輸入的第一個ID,都是後續ID的父節點,需要將後續ID的父節點數據成員指向這一ID。並且`層次=父節點層次+1。如果該節點有孩子結點,就將其數據成員Nochild置爲0,否則爲1.如果爲1,則表明這個結點就是一個葉子節點。
最終我們聲明一個level數組,level數組中的索引爲層數,值爲對應層數的葉子節點數。如何求得呢?
我們只需要遍歷所有結點:

for v in 所有節點:
	if(v.Nochild==1)//v點沒孩子結點
		lev[v.level]++;

代碼

#include<cstdio>
#include<cstring>
struct Node
{
 int father;
 int level;
 bool NoChild;
};
Node v[100];
char level[100]="\0";//level記錄的是某層葉結點數目,例如level[i]表示第i層葉子節點數目
int main()
{
 int N,M,c,ID,child,MAXLevel=1;//頂點數目,非葉子結點數目,指示某一頂點的孩子節點數目,頂點編號,頂點的孩子頂點,最大層數
    int i,j;
 scanf("%d%d",&N,&M);
 for(i=0;i<100;++i)
 {
  v[i].father=0;//指示父節點
  v[i].level=0;
  v[i].NoChild=1;
 }
 for(i=0;i<M;++i)
 {
  scanf("%d%d",&ID,&c);
  v[ID].NoChild=0;
  for(j=0;j<c;++j)
  {
   scanf("%d",&child);
   v[child].father=ID;
  }
 }
 v[1].level=1;
 for(i=1;i<=N;++i)
  for(j=1;j<=N;++j)
  {
   if(v[j].father==i)
   {
    v[j].level=v[v[j].father].level+1;
    if(v[j].level>MAXLevel)
     MAXLevel=v[j].level;//更新最大層數
   }
  }
    //遍歷所有頂點,找出那個所有葉子節點
 for(i=1;i<=N;++i)
  if(v[i].NoChild==1)
   level[v[i].level]++;//找出葉子結點,放入其所在層數位置
 for(i=1;i<MAXLevel;++i)//最大層數和頂點數目無關,所以我們需要單獨記錄最大層數
     printf("%d ",level[i]);
 printf("%d\n",level[i]);
 return 0;
}

答題用時16min
Q4——finish√

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章