1. 程式人生 > >pta 5-1 關於堆的判斷 (25分)

pta 5-1 關於堆的判斷 (25分)

5-1 關於堆的判斷 (25分)

將一系列給定數字順序插入一個初始為空的小頂堆H[]。隨後判斷一系列相關命題是否為真。命題分下列幾種:

  • x is the root:x是根結點;
  • x and y are siblings:x和y是兄弟結點;
  • x is the parent of y:x是y的父結點;
  • x is a child of y:x是y的一個子結點。

輸入格式:

每組測試第1行包含2個正整數N(≤1000)和M (≤ 20),分別是插入元素的個數、以及需要判斷的命題數。下一行給出區間[−10000,10000]內的N個要被插入一個初始為空的小頂堆的整數。之後M行,每行給出一個命題。題目保證命題中的結點鍵值都是存在的。

輸出格式:

對輸入的每個命題,如果其為真,則在一行中輸出T,否則輸出F。

輸入樣例:

5 4
46 23 26 24 10
24 is the root
26 and 23 are siblings
46 is the parent of 23
23 is a child of 10

輸出樣例:

F
T
F
T

程式碼:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <functional> using namespace std; vector<int> v; int Find(int a) {//查詢對應元素值的下標 return find(v.begin()+1, v.end(), a)-v.begin(); } int main(int argc, char const *argv[]) { int n, m, a, b; v.push_back(0);//0座標用掉,這樣比較方便 //父親結點就是i / 2 兒子結點2 * i or 2 * i + 1 char s[100
], tmp[4]; scanf("%d %d", &n, &m); for(int i = 0; i < n; ++i) { scanf("%d", &a); v.push_back(a); push_heap(v.begin()+1, v.end(), greater<int>());//對加入的元素構造最小堆 } scanf("%*c"); while(m--) { gets(s); if(s[strlen(s) - 1] == 't') { sscanf(s, "%d", &a);//提取字串裡面的數字 if(v[1] == a) printf("T\n");//如果是根結點 else printf("F\n"); } else if(s[strlen(s) - 1] == 's') { sscanf(s, "%d %*s %d", &a, &b); a = Find(a); b = Find(b); if(a/2 == b/2) printf("T\n");//兄弟結點 else printf("F\n"); } else { sscanf(s, "%d %*s %s %*s %*s %d", &a, tmp, &b); a = Find(a); b = Find(b); if(!strcmp(tmp, "the")) { if(a == b/2) printf("T\n");//a是b的父親結點 else printf("F\n"); } else { if(a/2 == b) printf("T\n");//a是b的兒子結點 else printf("F\n"); } } } return 0; }