PAT 天梯赛 L2-012. 关于堆的判断 【Heap】【STL】

题目链接

https://www.patest.cn/contests/gplt/L2-012

思路
使用 STL 里面有关 Heap 的函数
std::make_heap将[start, end)范围进行堆排序,默认使用less, 即最大元素放在第一个。

std::pop_heap将front(即第一个最大元素)移动到end的前部,同时将剩下的元素重新构造成(堆排序)一个新的heap。

std::push_heap对刚插入的(尾部)元素做堆排序。

std::sort_heap将一个堆做排序,最终成为一个有序的系列,可以看到sort_heap时,必须先是一个堆(两个特性:1、最大元素在第一个 2、添加或者删除元素以对数时间),因此必须先做一次make_heap.

make_heap, pop_heap, push_heap, sort_heap都是标准算法库里的模板函数,用于将存储在vector/deque 中的元素进行堆操作

根据 题目的意思 是要用 push_heap 一个一个 插入
而不能用 make_heap

因为 push_heap 和 make_heap 构造的堆 是不一样的
比如

3 6 2 4 1 5 这组数据

make_heap
这里写图片描述

push_heap
这里写图片描述

然后 用一个 map 将元素 与其 数组下标 对应起来 要从1 开始

根节点 就是判断一下 其数组下标 是不是 1

x 和 y 是兄弟节点
就是 判断一下
a = x 的数组下标 / 2
b = y 的数组下标 / 2
a 对应的数 和b 对应的数 是不是相等 并且 a != b

x 是 y 的父节点
就是 判断一下 y 的数组下标 / 2 是不是 等于 x 的数组下标
x 是

x 是 y 的子节点
就是 判断一下 x 的数组下标 / 2 是不是 等于 y 的数组下标

AC 代码

#include <cstdio>
#include <cstring>
#include <ctype.h>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <map>
#include <stack>
#include <set>
#include <numeric>
#include <sstream>
#include <iomanip>
#include <limits>

#define CLR(a) memset(a, 0, sizeof(a))

using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair<string, int> psi;
typedef pair<string, string> pss;

const double PI = 3.14159265358979323846264338327;
const double E = exp(1);
const double eps = 1e-6;

const int INF = 0x3f3f3f3f;
const int maxn = 1e3 + 5;
const int MOD = 1e9 + 7;

int main()
{
    map <int, int> vis;
    int n, m, num;
    scanf("%d%d", &n, &m);
    vector <int> v;
    for (int i = 0; i < n; i++)
    {
        scanf("%d", &num);
        num = -num;
        v.push_back(num);
        push_heap(v.begin(), v.end());
    }
    for (int i = 0; i < n; i++)
        vis[-v[i]] = i + 1;
    while (m--)
    {
        int a, b, c, d;
        string s;
        cin >> a;
        cin >> s;
        if (s == "and")  //2
        {
            cin >> b;
            cin >> s;
            cin >> s;
            c = vis[a];
            d = vis[b];
            if (v[c / 2] == v[d / 2] && c != d)
                cout << "T\n";
            else
                cout << "F\n";
        }
        else
        {
            cin >> s;
            if (s == "the")
            {
                cin >> s;
                if (s == "root")  //1
                {
                    if (vis[a] == 1)
                        cout << "T\n";
                    else
                        cout << "F\n";
                }
                else    // 3
                {
                    cin >> s;
                    cin >> b;
                    c = vis[a];
                    d = vis[b];
                    if (d / 2 == c)
                        cout << "T\n";
                    else
                        cout << "F\n";
                }
            }
            else  //4
            {
                cin >> s;
                cin >> s;
                cin >> b;
                c = vis[a];
                d = vis[b];
                if (c / 2 == d)
                    cout << "T\n";
                else
                    cout << "F\n";
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值