团体天梯练习 L2-012 关于堆的判断
L2-012 关于堆的判断
将一系列给定数字顺序插入一个初始为空的小顶堆 \(H\) [ ] 。随后判断一系列相关命题是否为真。命题分下列几种:
• \(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
解题思路
按照题意不断进行堆的向上调整操作,得到小顶堆,并记录每个值所在下标,看作是一颗完全二叉树。注意要使用在线调整的 \(up\) 向上调整法,如果使用离线调整的 \(down\) 向下调整法,得到的小顶堆不一定相同。
/* 一切都是命运石之门的选择 El Psy Kongroo */
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#include<deque>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<cmath>
#include<functional>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<int, pii> piii;
typedef pair<double, double> pdd;
typedef pair<string, int> psi;
typedef __int128 int128;
#define PI acos(-1.0)
#define x first
#define y second
//int dx[4] = {1, -1, 0, 0};
//int dy[4] = {0, 0, 1, -1};
const int inf = 0x3f3f3f3f, mod = 1e9 + 7;
map<int, int> idx;
static const int N = 1010;
int a[N], n, m;
//向上调整法
void up(int u){
while(u >> 1 && a[u] < a[u >> 1]){
swap(a[u], a[u >> 1]);
u >>= 1;
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin >> n >> m;
for(int i = 1; i <= n; i ++ ){
cin >> a[i];
up(i); //在线调整
}
for(int i = 1; i <= n; i ++ ) idx[a[i]] = i;
while(m -- ){
bool flag;
int x, y; cin >> x;
string s; cin >> s; //cin不吸收空格
if(s == "and"){
cin >> y; cin >> s >> s;
flag = (idx[x] / 2 == idx[y] / 2); //两者的父节点下标是否相同
}else{
cin >> s >> s;
if(s == "root") flag = (idx[x] == 1); //下标为1即为根节点
else if(s == "parent"){
cin >> s; cin >> y;
flag = (idx[x] == idx[y] / 2); //x是y的父节点 判断x的下标是否为y下标的1/2向下取整
}else{
cin >> s; cin >> y;
flag = (idx[x] / 2 == idx[y]); //x是y的子节点 判断y的下标是否为x下标的1/2向下取整
}
}
if(flag) cout << "T" << endl;
else cout << "F" << endl;
}
return 0;
}
一切都是命运石之门的选择,本文章来源于博客园,作者:MarisaMagic,出处:https://www.cnblogs.com/MarisaMagic/p/17325876.html,未经允许严禁转载