天天看點

DS部落格作業05--樹1.本周學習總結2.PTA實驗作業3.閱讀代碼4. 上機考試(不計分)以上

目錄

  • 1.本周學習總結
    • 1.1思維導圖
    • 1.2談談你對樹結構的認識及學習體會
  • 2.PTA實驗作業
    • 2.1.題目1:朋友圈
      • 2.1.1設計思路
      • 2.1.2代碼截圖
      • 2.1.3本題PTA送出清單說明
    • 2.2.題目2:修理牧場
      • 2.2.1設計思路
      • 2.2.2代碼截圖
      • 2.2.3本題PTA送出清單說明
    • 2.3.題目3:家譜處理
      • 2.3.1設計思路
      • 2.3.2代碼截圖
      • 2.3.3本題PTA送出清單說明
  • 3.閱讀代碼
    • 3.1 題目
      • Description
      • Input
      • Output
      • Sample
    • 3.2 解題思路
    • 3.3 代碼截圖
    • 3.4 學習體會
  • 4. 上機考試(不計分)
  • 以上

1.本周學習總結

1.1思維導圖

DS部落格作業05--樹1.本周學習總結2.PTA實驗作業3.閱讀代碼4. 上機考試(不計分)以上

1.2談談你對樹結構的認識及學習體會

樹結構還是很有意思的,因為以前總是要寫很多代碼,現在到了樹的結構,大多數都是直接用遞歸,代碼量少(個别題目除外)。其實最主要的就是二叉樹,不管是樹還是森林,都可以轉換成二叉樹,在這個基礎上進行操作,其中印象最深的的就是目錄樹了,雖然說操作起來有點麻煩,但是看到最終的結果還是十分有成就感的。但是結合之前知識點的題目又有點力不足的感覺,例如表達式樹,究其原因應該是沒有複習的鍋了。樹在生活中還是很多的,不僅僅是友善查找和存儲資料,同時其中的哈夫曼樹又可以用于資料的加密,涉及到一點密碼學的内容,真的是很有意思了。

2.PTA實驗作業

2.1.題目1:朋友圈

某學校有N個學生,形成M個俱樂部。每個俱樂部裡的學生有着一定相似的興趣愛好,形成一個朋友圈。一個學生可以同時屬于若幹個不同的俱樂部。根據“我的朋友的朋友也是我的朋友”這個推論可以得出,如果A和B是朋友,且B和C是朋友,則A和C也是朋友。請編寫程式計算最大朋友圈中有多少人。

輸入格式:

輸入的第一行包含兩個正整數N(≤30000)和M(≤1000),分别代表學校的學生總數和俱樂部的個數。後面的M行每行按以下格式給出1個俱樂部的資訊,其中學生從1~N編号:第i個俱樂部的人數Mi(空格)學生1(空格)學生2 … 學生Mi

輸出格式:

輸出給出一個整數,表示在最大朋友圈中有多少人。

2.1.1設計思路

//對于每個朋友圈,我們設立一個boss,代表這個朋友圈的頭頭
//并且設立一個全局數組用來存儲每個人對應的boss資訊
//我們想得到的結果是朋友圈中所有人的boss是同一個人

全局變量:circle數組//用于存儲boss資訊
find函數:int x //這是傳參,下同,函數功能是查找x的boss
    查找x在circle中的boss,如果x本身就是一個boss,傳回x;
    如果不是,繼續遞歸find(circle[x]),一級一級地找x的最終boss,并将boss的值傳回,賦予circle[x]
    //将傳回的boss的值賦予circle[x]很重要,因為所有圈中的boss可能合并導緻boss改變
    傳回x的boss

unit函數:int person1,int person2//功能:聯合person1和person2所在的朋友圈
    find函數查找person1的boss
    find函數查找person2的boss
    如果兩人的boss不相同,就讓person2的boss做person1的boss的小弟
    //也就是令person2的boss在數組中對應的值為person1的boss

main函數:
    cin >> m,n
    根據m對circle數組初始化
    while(n--)//讀入朋友圈
        讀取第一個人bigBoss作為這個朋友圈的boss
        讀入剩下的所有人,并用unit函數将他們聯合為一個朋友圈
        //在未聯合之前,每個人都是自己的boss
    static int result[]//統計每個boss小弟人數
    int max = 0//最大值
    for i = 1 to m:
        int b = i 的boss
        result[b]++
        if result[b] > max:
            max=result
    cout << max
    
           
題外話:其實這道題我在樹的PTA裡面是沒有寫的,因為我以為考試後題組還會開放。。就隻記了思路,并未實踐
DS部落格作業05--樹1.本周學習總結2.PTA實驗作業3.閱讀代碼4. 上機考試(不計分)以上
。不過我在固定題目集裡面找到了這道題,并用下面的代碼成功通過。

2.1.2代碼截圖

DS部落格作業05--樹1.本周學習總結2.PTA實驗作業3.閱讀代碼4. 上機考試(不計分)以上

2.1.3本題PTA送出清單說明

DS部落格作業05--樹1.本周學習總結2.PTA實驗作業3.閱讀代碼4. 上機考試(不計分)以上
WA:第一次送出出錯是因為我在unit函數中令person2的boss等于person1,而未對兩者的boss進行操作。導緻這兩個小弟謎之叛變。。。。

2.2.題目2:修理牧場

2.2.1設計思路

這道題目其實就是個閹割版的哈夫曼樹生成,因為你不需要最後的樹結構,是以這道題目其實可以隻用一個數組解決

main函數:
    int wood數組
    for i = 1 to n:
        讀入每根木頭的長度
    sort函數對wood數組進行快速排序//畢竟C++有,就直接用了。不然冒泡半天
    for i = 0 to n-2:
        将wood[i]和wood[i+1]相加得到和plus
        sum += plus //sum為總消費
        将和按照升序插入到後面的數組中//本想着這裡也用sort但是後面實驗了發現會逾時
    cout << sum
           
DS部落格作業05--樹1.本周學習總結2.PTA實驗作業3.閱讀代碼4. 上機考試(不計分)以上

2.2.2代碼截圖

DS部落格作業05--樹1.本周學習總結2.PTA實驗作業3.閱讀代碼4. 上機考試(不計分)以上

2.2.3本題PTA送出清單說明

DS部落格作業05--樹1.本周學習總結2.PTA實驗作業3.閱讀代碼4. 上機考試(不計分)以上

2.3.題目3:家譜處理

人類學研究對于家族很感興趣,于是研究人員搜集了一些家族的家譜進行研究。實驗中,使用計算機處理家譜。為了實作這個目的,研究人員将家譜轉換為文本檔案。下面為家譜文本檔案的執行個體:
John
  Robert
    Frank
    Andrew
  Nancy
    David
           
家譜文本檔案中,每一行包含一個人的名字。第一行中的名字是這個家族最早的祖先。家譜僅包含最早祖先的後代,而他們的丈夫或妻子不出現在家譜中。每個人的子女比父母多縮進2個空格。以上述家譜文本檔案為例,John這個家族最早的祖先,他有兩個子女Robert和Nancy,Robert有兩個子女Frank和Andrew,Nancy隻有一個子女David。在實驗中,研究人員還收集了家庭檔案,并提取了家譜中有關兩個人關系的陳述語句。下面為家譜中關系的陳述語句執行個體:
John is the parent of Robert
Robert is a sibling of Nancy
David is a descendant of Robert
           
研究人員需要判斷每個陳述語句是真還是假,請編寫程式幫助研究人員判斷。

輸入格式:

輸入首先給出2個正整數N(2≤N≤100)和M(≤100),其中N為家譜中名字的數量,M為家譜中陳述語句的數量,輸入的每行不超過70個字元。名字的字元串由不超過10個英文字母組成。在家譜中的第一行給出的名字前沒有縮進空格。家譜中的其他名字至少縮進2個空格,即他們是家譜中最早祖先(第一行給出的名字)的後代,且如果家譜中一個名字前縮進k個空格,則下一行中名字至多縮進k+2個空格。在一個家譜中同樣的名字不會出現兩次,且家譜中沒有出現的名字不會出現在陳述語句中。每句陳述語句格式如下,其中X和Y為家譜中的不同名字:
X is a child of Y
X is the parent of Y
X is a sibling of Y
X is a descendant of Y
X is an ancestor of Y
           

輸出格式:

對于測試用例中的每句陳述語句,在一行中輸出True,如果陳述為真,或False,如果陳述為假。

2.3.1設計思路

這題同樣也是在固定題目集過的

cin不能讀入空格,是以這裡得用getline,還有就是存儲在map的時候是不能帶空格的,然後string沒有trim這樣的去空格函數,是以就隻好自己寫一個

//讀取人物關系資訊
map<string, string> relation
stack<string> family
while(1)
    讀取一個人名name
    if 空棧:
        直接入棧
        continue
    if 棧頂是 name的父親:
        relation[name] = 棧頂//建立關系
        入棧name
    else
        不斷退棧直到棧頂是name的父親
        relation[name] = 棧頂
        入棧name
           
//解決輸入的問題,采用遞歸
solve函數:string name1,name2,re//re是關系
switch(re[0])
    case c:判斷name2是否是name1的父親,傳回判斷結果//判斷是不是兒子
    case p:同上//判斷是不是父母
    case s:同上//判斷是不是兄弟
    case a:GrandSearch(name1,name2,re)//判斷是不是祖先
    case d:GrandSearch(name2,name1,re)//判斷是不是祖孫

GrandSearch函數:
    if name1是唯一的祖先:
        return false
    if name1的父親是name2:
        return true
    else return GrandSearch(name1的父親,name2)//遞歸函數不好講,,就是不斷找name1的父親,直到找不到或者name1的父親就是name2為止
           

2.3.2代碼截圖

DS部落格作業05--樹1.本周學習總結2.PTA實驗作業3.閱讀代碼4. 上機考試(不計分)以上
DS部落格作業05--樹1.本周學習總結2.PTA實驗作業3.閱讀代碼4. 上機考試(不計分)以上

2.3.3本題PTA送出清單說明

DS部落格作業05--樹1.本周學習總結2.PTA實驗作業3.閱讀代碼4. 上機考試(不計分)以上
WA:之是以一直過不去是因為我以為每一行的空格與下一行的空格相差隻有2,0,-2,是以沒有用if包括進去,其實不止,還可能是任何負偶數,如下面的David和上一行的Nancy就差了6,修改一下if語句的條件就好辣
John
  Robert
    Frank
      Andrew
        Nancy
  David
           
DS部落格作業05--樹1.本周學習總結2.PTA實驗作業3.閱讀代碼4. 上機考試(不計分)以上

3.閱讀代碼

3.1 題目

這次省賽ACM剛好遇到一題有關樹的題目,可以拿出來看看

Description

It is known that there are N cats in Quasrain's home. The weight of cat i is A[i]. As Quasrain is evil, he wants to do something to the cats.

Practicing for two years and a half, the cats have gotten the commands of Quasrain. Whenever Quasrain say a a color, the cats in the actual color would come out, and Quasrain would cost sum of their weight. For example, now Quasrain has three cats in red, weights of {1,2,3}, and two cats in green, weights of {7,8} .If he says red, he would cost 6 (green for 15). Then he would choose some of them, would never stop until there isn't any pair of cats with the same color.

Initially, the cats are all in color white. Quasrain want to know, how much he wanld cost at least.

Input

The first line is a number N(2<=N<=10^5)

Then one line with N numbers, A[i] for the weight of cats i.(1<=A[i]<=10^9)

Output

Only one number, representing the least cost of Quasrain.

Sample

Input:

4

6 7 70 25

Output:

159

3.2 解題思路

起初我研究了一下樣例,以為是每次叫一個最多數量顔色的貓,然後給裡面其中一隻上色,循環這個過程得到的最終答案,但是後面代碼實作後送出上去是個WA。經過小組隊員的一番bug測試,最終确定這是一道哈夫曼樹類型題。并決定采用優先隊列來解決。
           
将所有的貓的weight全部放進一個使用小頂堆的優先隊列q;
int sum=0;
while(q.size()!=1)
    出隊權值最小的兩項并求和plus;
    入隊plus;
    sum+=plus;
輸出sum;
    
           

3.3 代碼截圖

DS部落格作業05--樹1.本周學習總結2.PTA實驗作業3.閱讀代碼4. 上機考試(不計分)以上

3.4 學習體會

這道題其實一開始真的沒看出來是哈夫曼樹的題目,但是後面根據隊友找的的一組資料,就是四隻100的貓要進行操作的時候,發現應該先把四隻全叫出來塗色兩隻,然後就得到了兩種顔色各有兩隻的貓,這時隻要每種顔色叫一次然後塗色一隻就可以達到最低消費。現在想起來這種題目更像是哈夫曼樹生成的逆過程,哈夫曼樹一開始不是要選擇最小的兩個嘛,是從葉子節點開始,合并生成根節點的過程。而叫貓一開始是要全部叫出來,然後分解為一隻隻不同顔色的貓的過程。過程相反,實作則相同,以後遇到這類題目都可以考慮采用優先隊列來解決。

4. 上機考試(不計分)

果然表達式樹還是沒掌握好啊

問題1:

DS部落格作業05--樹1.本周學習總結2.PTA實驗作業3.閱讀代碼4. 上機考試(不計分)以上

講真的我也不知道自己怎麼寫出這東西來的,我當時就坐在那眼睜睜看着給t->data指派‘1’,結果t->data裡面的資料變成’?‘,然後心裡充滿了'?????????????'

問題2:

DS部落格作業05--樹1.本周學習總結2.PTA實驗作業3.閱讀代碼4. 上機考試(不計分)以上

一直卡在第一個問題,是以這個錯誤我也沒有去找,就是将兩個數和一個運算符合成一棵樹時忘記把運算符也出棧了。。

修改後:

DS部落格作業05--樹1.本周學習總結2.PTA實驗作業3.閱讀代碼4. 上機考試(不計分)以上

以上

DS部落格作業05--樹1.本周學習總結2.PTA實驗作業3.閱讀代碼4. 上機考試(不計分)以上

轉載于:https://www.cnblogs.com/Rasang/p/10870304.html