关于堆的判断

本专栏持续输出数据结构题目集,欢迎订阅。

文章目录

    • 题目
    • 代码

题目

将一系列给定数字顺序插入一个初始为空的最小堆。随后判断一系列相关命题是否为真。命题分下列几种:

  • 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 
#include 
#include 

#define MAXN 1001
#define INF 0x7FFFFFFF

int 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 root
        sscanf(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 siblings
        sscanf(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 y
        sscanf(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 y
        sscanf(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;
}    

你可能感兴趣的:(PTA,数据结构题目集,算法,数据结构,c语言)