PAT(甲级)2021年春季考试 Structure of Max-Heap (最大堆)

Problem
In computer science, a max-heap is a specialized tree-based data structure that satisfies the heap property: if P is a parent node of C, then the key (the value) of P is greater than or equal to the key of C. A common implementation of a heap is the binary heap, in which the tree is a complete binary tree.

Your job is to first insert a given sequence of integers into an initially empty max-heap, then to judge if a given description of the resulting heap structure is correct or not. There are 5 different kinds of description statements:

x is the root
x and y are siblings
x is the parent of y
x is the left child of y
x is the right child of y

Input Specification:
Each input file contains one test case. For each case, the first line gives 2 positive integers: N (≤1,000), the number of keys to be inserted, and M (≤20), the number of statements to be judged. Then the next line contains N distinct integer keys in [−10​4,104] which are supposed to be inserted into an initially empty max-heap. Finally there are M lines of statements, each occupies a line.

Output Specification:
For each statement, print 1 if it is true, or 0 if not. All the answers must be print in one line, without any space.

Sample Input:

5 6
23 46 26 35 88
35 is the root
46 and 26 are siblings
88 is the parent of 46
35 is the left child of 26
35 is the right child of 46
-1 is the root

Sample Output:

011010

Method
根据题意依次向堆中插入元素,接着按照题意模拟即可。

易错点:
1.输入的顶点可能没有在堆内出现过,需要特判。
2.必须按照题意依次插入元素,不可以一次性将所有元素录入到数组中然后进最大堆的建立,这样建立得到的结果与依次插入形成的最大堆不同。
3.判断是不是sibilings的时候可能输入的两个数据都相等,需要特判。(但是测试点并没有考查这个的,写的时候可以顺带优化一下,以免以后被坑…)

Code

#include<bits/stdc++.h>
using namespace std;
int n, m, tree[100005];
void siftup(int i)
{
    while(i != 1)
    {
        if(tree[i] > tree[i/2])
        {
        	swap(tree[i], tree[i/2]);
        	i = i / 2;
		}
		else 
		    break;
    }
}

int find(int x)
{
    for(int i = 1; i <= n; i++)
        if(tree[i] == x)
            return i;
    return -1;
}

int main()
{
	cin >> n >> m;
    for(int i = 1; i <= n; i++)
    {
        cin >> tree[i];
        siftup(i);
    }
    int a, b;
    string s1, s2;
    for(int i = 0; i < m; i++)
    {
        cin >> a >> s1;
        if(s1 == "and")
        {
            cin >> b >> s2 >> s2;
            if(find(a) / 2 == find(b) / 2 && find(a) != -1 && find(b) != -1)
                cout << 1;
            else 
                cout << 0;
        }
        else
        {
            cin >> s1 >> s1;
            if(s1 == "root")
            {
                if(find(a) == 1)
                    cout << 1;
                else 
                    cout << 0;
            }
            else if(s1 == "parent")
            {
                cin >> s2 >> b;
                if(find(b) / 2 == find(a) && find(a) != -1 && find(b) != -1)
                    cout << 1;
                else 
                    cout << 0;
            }
            else if(s1 == "left")
            {
                cin >> s2 >> s2 >> b;
                if(find(a) == find(b)*2 && find(a) != -1 && find(b) != -1)
                    cout << 1;
                else 
                    cout << 0;
            }
            else if(s1 == "right")
            {
                cin >> s2 >> s2 >> b;
                if(find(a) == find(b)*2+1 && find(a) != -1 && find(b) != -1)
                    cout << 1;
                else 
                    cout << 0;
            }
        }
    }
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值