本專欄持續輸出數據結構題目集,歡迎訂閱。
文章目錄
- 題目
- 代碼
題目
將一系列給定數字順序插入一個初始為空的最小堆。隨后判斷一系列相關命題是否為真。命題分下列幾種:
- 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
題目引用自團體程序設計天梯賽真題(2016年)。
代碼
#include <stdio.h>
#include <stdlib.h>
#include <string.h>#define MAXN 1001
#define INF 0x7FFFFFFFint h[MAXN], size;
int pos[20001]; // 記錄每個值在堆中的位置,值范圍[-10000,10000],映射到[0,20000]// 初始化堆
void Create() {size = 0;h[0] = -INF; // 哨兵,小于所有可能的元素值memset(pos, 0, sizeof(pos)); // 初始化位置數組
}// 插入元素到最小堆
void Insert(int x) {int i;for (i = ++size; h[i/2] > x; i /= 2) {h[i] = h[i/2]; // 上濾pos[h[i] + 10000] = i; // 更新位置}h[i] = x;pos[x + 10000] = i; // 記錄新元素的位置
}// 判斷命題
void Judge(char *statement) {int x, y;char op1[20], op2[20], op3[20];// 解析命題if (strstr(statement, "is the root")) {// 情況1: x is the rootsscanf(statement, "%d is the root", &x);printf("%c\n", (h[1] == x) ? 'T' : 'F');} else if (strstr(statement, "and") && strstr(statement, "are siblings")) {// 情況2: x and y are siblingssscanf(statement, "%d and %d are siblings", &x, &y);int posX = pos[x + 10000];int posY = pos[y + 10000];printf("%c\n", (posX/2 == posY/2) ? 'T' : 'F');} else if (strstr(statement, "is the parent of")) {// 情況3: x is the parent of ysscanf(statement, "%d is the parent of %d", &x, &y);int posX = pos[x + 10000];int posY = pos[y + 10000];printf("%c\n", (posY/2 == posX) ? 'T' : 'F');} else if (strstr(statement, "is a child of")) {// 情況4: x is a child of ysscanf(statement, "%d is a child of %d", &x, &y);int posX = pos[x + 10000];int posY = pos[y + 10000];printf("%c\n", (posX/2 == posY) ? 'T' : 'F');}
}int main() {int n, m, i, x;char statement[100];// 讀取輸入scanf("%d %d", &n, &m);// 構建最小堆Create();for (i = 0; i < n; i++) {scanf("%d", &x);Insert(x);}// 處理命題getchar(); // 消耗掉scanf后的換行符for (i = 0; i < m; i++) {fgets(statement, sizeof(statement), stdin);statement[strcspn(statement, "\n")] = 0; // 去掉換行符Judge(statement);}return 0;
}