PAT L2-012 关于堆的判断

https://pintia.cn/problem-sets/994805046380707840/problems/994805064676261888

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

  • x is the rootx是根结点;
  • x and y are siblingsxy是兄弟结点;
  • x is the parent of yxy的父结点;
  • x is a child of yxy的一个子结点。

输入格式:

每组测试第1行包含2个正整数N≤ 1000)和M≤ 20),分别是插入元素的个数、以及需要判断的命题数。下一行给出区间[内的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 <bits/stdc++.h>
using namespace std;

const int maxn = 2e5 + 10;
int N, M;
int A[maxn], pos[maxn];

void minHeapify(int i){
    if(i==1) return;

    while(i > 1){
        if(A[i] < A[i / 2]){
            swap(A[i], A[i / 2]);
            i /= 2;
        } else return;
    }
}

int get_num(int l, int r, string s) {

    int i = l, num = 0;
    if(s[l] == '-')
        i ++;
    for(; i <= r; i ++)
        num = num * 10 + (s[i] - '0');
    if(s[l] == '-')
        return 10000 - num;
    return 10000 + num;
}

int main() {
    scanf("%d%d", &N, &M);
    for(int i = 1; i <= N; i ++)
        scanf("%d", &A[i]);

    getchar();
    for(int i = 1; i <= N; i ++)
        minHeapify(i);

    for(int i = 1; i <= N; i ++)
        pos[A[i] + 10000] = i;


    string s;
    for(int m = 0; m < M; m ++) {
        getline(cin, s);
        string t1 = "", t2 = "";
        int len = s.length();
        int temp = 0, temp1 = 0, temp2 = 0;
        int num1 = 0, num2 = 0, cnt = 0;
        if(s.find("root") != -1) {

            for(int i = 0; i < len; i ++) {
                if(s[i] == ' ') {
                    temp = i - 1;
                    break;
                }
            }

            num1 = get_num(0, temp, s);

            if(num1 == A[1] + 10000) printf("T
");
            else printf("F
");
        } else if(s[len - 1] == 's') {
            for(int i = 0; i < len; i ++) {
                if(s[i] == ' ') {
                    cnt ++;
                    if(cnt == 1) temp = i - 1;
                    if(cnt == 2) temp1 = i + 1;
                    if(cnt == 3) temp2 = i - 1;
                }
            }

            num1 = get_num(0, temp, s);
            num2 = get_num(temp1, temp2, s);

            if((pos[num1] / 2) == (pos[num2] / 2)) printf("T
");
            else printf("F
");
        } else if(s.find("child") != -1) {
            temp2 = len - 1;
            for(int i = 0; i < len; i ++) {
                if(s[i] == ' ') {
                    cnt ++;
                    if(cnt == 1) temp = i - 1;
                    else if(cnt == 5) temp1 = i + 1;
                }
            }

            num1 = get_num(0, temp, s);
            num2 = get_num(temp1, temp2, s);

            if(pos[num1] / 2 == pos[num2]) printf("T
");
            else printf("F
");
        } else {
            temp2 = len - 1;
            for(int i = 0; i < len; i ++) {
                if(s[i] == ' ') {
                    cnt ++;
                    if(cnt == 1) temp = i - 1;
                    else if(cnt == 5) temp1 = i + 1;
                }
            }

            num1 = get_num(0, temp, s);
            num2 = get_num(temp1, temp2, s);

            if(pos[num2] / 2 == pos[num1]) printf("T
");
            else printf("F
");
        }
    }


    return 0;
}

  历尽波折 先是输入数组之后吸掉换行 然后没仔细看数组数字还有负数数组越界每个数字加 10000 然后建最小堆写错了题目要按顺序插入 落泪

原文地址:https://www.cnblogs.com/zlrrrr/p/10521259.html