noip第21課作業


1. 遍歷二叉樹

【問題描述】

以先序的方式建立一棵二叉樹,空結點用‘#’號表示,例如:abd###ce##f##,將建立一棵如下的二叉樹:

輸出其中序序列和后序序列,其中總結點個數不超過100。

輸入:僅一行,輸入一串字符串,該字符串必須能構成一棵二叉樹;

輸出:兩行,第一行為中序序列,第二行為后序序列。

【樣例輸入】

 abd###ce##f##

【樣例輸出】

dbaecf

dbefca

#include<iostream>
using namespace std;
struct node{
    char value;
    int left,right;//左右孩子子樹
}data[100]; 
char ch;
int cnt,root;
//建立一棵二叉樹   abd###ce##f##
int buildTree(int bt){
    cin >> ch;
    if(ch == '#'){
        bt = 0;
    }
    else{
        bt = ++cnt;
        data[bt].value = ch;
        data[bt].left = data[bt].right = 0;
        data[bt].left = buildTree(bt);
        data[bt].right = buildTree(bt);
    }
    return bt;
} 
//中序序列
void MidTree(int bt){
    if(bt){
        MidTree(data[bt].left);
        cout << data[bt].value;
        MidTree(data[bt].right);
    }
} 
//后序序列
void LastTree(int bt){
    if(bt){
        LastTree(data[bt].left);
        LastTree(data[bt].right);
        cout << data[bt].value;
    }
} 
int main()
{
    root = 0;
    cnt = 0;
    root = buildTree(0);    
    MidTree(root);
    cout << endl;
    LastTree(root); 
    return 0;
}

2. 計算二叉樹的結點個數

【問題描述】

以先序的方式建立一棵二叉樹,空結點用‘#’號表示,例如:abd###ce##f##,將建立一棵如下的二叉樹:

輸出其總結點的個數,其中總結點個數不超過100。

輸入:僅一行,輸入一串字符串,該字符串必須能構成一棵二叉樹;

輸出:僅一行,為該二叉樹的結點個數。

【樣例輸入】

 abd###ce##f##

【樣例輸出】

 6

#include<iostream>
using namespace std;
struct node{
    char value;
    int left,right;//左右孩子子樹
}data[100]; 
char ch;
int cnt,root;
//建立一棵二叉樹   abd###ce##f##
int buildTree(int bt){
    cin >> ch;
    if(ch == '#'){
        bt = 0;
    }
    else{
        bt = ++cnt;
        data[bt].value = ch;
        data[bt].left = data[bt].right = 0;
        data[bt].left = buildTree(bt);
        data[bt].right = buildTree(bt);
    }
    return bt;
} 
//計算結點數
int Node(int bt){
    if(bt){
        if(data[bt].left == 0 && data[bt].right == 0)  return 1;
        else return Node(data[bt].left)+Node(data[bt].right) + 1;
    }
    else return 0;
} 
int main()
{
    root = 0;
    cnt = 0;
    root = buildTree(0);
    cout << Node(root) << endl;
    return 0;
}

3. 計算二叉樹的葉子結點個數

【問題描述】

以先序的方式建立一棵二叉樹,空結點用‘#’號表示,例如:abd###ce##f##,將建立一棵如下的二叉樹:

輸出其葉子結點的個數,其中總結點個數不超過100。

輸入:僅一行,輸入一串字符串,該字符串必須能構成一棵二叉樹;

輸出:僅一行,為該二叉樹的葉子結點的個數。

【樣例輸入】

 abd###ce##f##

【樣例輸出】

 3

#include<iostream>
using namespace std;
struct node{
    char value;
    int left,right;//左右孩子子樹
}data[100]; 
char ch;
int cnt,root;
//建立一棵二叉樹   abd###ce##f##
int buildTree(int bt){
    cin >> ch;
    if(ch == '#'){
        bt = 0;
    }
    else{
        bt = ++cnt;
        data[bt].value = ch;
        data[bt].left = data[bt].right = 0;
        data[bt].left = buildTree(bt);
        data[bt].right = buildTree(bt);
    }
    return bt;
} 
//計算葉子數
int Leaf(int bt){
    if(bt){
        if(data[bt].left == 0 && data[bt].right == 0){
            return 1;
        }
        else return Leaf(data[bt].left)+Leaf(data[bt].right);
    }
    else return 0;
}
int main()
{
    root = 0;
    cnt = 0;
    root = buildTree(0);
    cout << Leaf(root) << endl;
    return 0;
}

4. 解密犯罪團伙

【問題描述】

快過年了,犯罪分子們也開始為年終獎“奮斗”了,小明的家鄉出現了多次搶劫事件。由於強盜人數過於龐大,作案頻繁,警方想查清楚到底有幾個犯罪團伙實在是太不容易了,不過呢,經過很多天的努力,警察叔叔還是搜集到了一些線索,需要聰明的我們編寫程序幫助警察叔叔分析一下有多少個獨立的犯罪團伙?

輸入格式:輸入第一行為n,m,n表示強盜的人數,m表示警方搜集到的m條線索。接下來m行每一行有兩個數a,b,表示強盜a和強盜b是通過。

數據范圍說明:(1≤n≤20000),(1≤m≤1000000),1≤a,b≤n。

【輸入樣例】              

10 9

1 2

3 4

5 2

4 6

2 6

8 7

9 7

1 6

2 4

【輸出樣例】

3

#include<iostream>
using namespace std;
int f[1000] = {},n,m,k,sum = 0;
//數組初始化,數組里存的是自己的下標 
void init(){
    for(int i = 1; i <= n; i++){
        f[i] = i;
    } 
}
//查找過程
int getf(int v){
    if(f[v] == v){
        return v;
    }
    else{
        f[v] = getf(f[v]); 
        return f[v];
    }
}
//合並的過程
void merge(int x, int y){
    int t1,t2;
    t1 = getf(x);
    t2 = getf(y);
    if(t1 != t2){
        f[t2] = t1;
    }
} 
int main()
{
    int i,x,y;
    cin >> n >> m;
    init();
    for(i = 1; i <= m; i++){
        cin >> x >> y;
        merge(x,y);
    }
    for(i = 1; i <= n; i++){
        if(f[i] == i) sum++;
    }
    cout << sum << endl;
    return 0;
}

1. 小球下落

【問題描述】

  許多的小球一個一個的從一棵滿二叉樹上掉下來組成FBT(Full Binary Tree,滿二叉樹),每一時間,一個正在下降的球第一個訪問的是非葉子節點。然后繼續下降時,或者走右子樹,或者走左子樹,直到訪問到葉子節點。決定球運動方向的是每個節點的布爾值。最初,所有的節點都是false,當訪問到一個節點時,如果這個節點時false,則這個球把它變成true,然后從左子樹走,繼續他的旅程。如果節點時true,則球也會改變它為false,而接下來從右子樹走。滿二叉樹的標記方法如下圖:

 

因為所有的節點最初為false,所以第一個球將會訪問節點1,節點2和節點4,轉變節點的布爾值后在節點8停止。第二個球將會訪問節點1,3,6,在節點12停止。明顯地,第三個球在它停止之前,會訪問節點1,2,5,在節點10停止。現在你的任務是,給定FBT的深度D,和I,表示第I個小球下落,你可以假定I不超過給定的FBT的葉子樹,寫一個程序求小球停止時的葉子序號。

輸入:僅一行,包含兩個用空格隔開的整數D和I(2≤D≤20,I≤I≤524288)。

輸出:對應輸出第1個小球下落停止時的葉子序號。

【樣例輸入】4 2

【樣例輸出】12

#include<iostream>
using namespace std;
bool tree[1024*1024];
int main()
{
    int d,k,i,j,p;
    cin >> d >> k;
    for(i = 1; i <= k; i++){  //枚舉每一個球的下落情況
        p = 1;
        for(j = 1; j < d; j++){   
            if(tree[p] == false){  //結點的值為0 
                tree[p] = true;
                p *= 2;            //向左走 
            }
            else{                  //結點的值為 1 
                tree[p] = false;  
                p = p*2+1;        //向右走 
            }
        }
    }
    cout << p << endl;
    return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM