将一系列给定数字插入一个初始为空的小顶堆H[]。随后对任意给定的下标i,打印从H[i]到根结点的路径。
输入格式:
每组测试第1行包含2个正整数N和M(≤1000),分别是插入元素的个数、以及需要打印的路径条数。下一行给出区间[-10000, 10000]内的N个要被插入一个初始为空的小顶堆的整数。最后一行给出M个下标。
输出格式:
对输入中给出的每个下标i,在一行中输出从H[i]到根结点的路径上的数据。数字间以1个空格分隔,行末不得有多余空格。
输入样例:
5 3
46 23 26 24 10
5 4 3
输出样例:
24 23 10
46 23 10
26 10
分析: 我们真的建树的话会很麻烦,和线段树一样,我们用一维数组来模拟二叉树的结构,(因为其父节点和孩子节点的标号 很有规律)。
看代码
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int N = 1000+11;
const int M = 1e6+11;
const int mod = 1e9+7;
const int inf = 0x3f3f3f3f;
const LL inff = 0x3f3f3f3f3f3f3f3f;
int H[N],sz;
void Creat(){
sz=0;
H[0]=-inf;
}
void Insert(int x){
int i;
for(i=++sz;H[i/2]>x;i/=2) // 如果比父节点的值小那么就要交换一下,不断交换,直到大于父节点
H[i]=H[i/2];
H[i]=x;
}
void Out(int id){
printf("%d",H[id]);
while(id>1){
id/=2;
printf(" %d",H[id]);
}
puts("");
}
int main(){
int n,m; scanf("%d%d",&n,&m);
Creat();
for(int i =0;i<n;i++){
int z;scanf("%d",&z);
Insert(z);
}
while(m--){
int z;scanf("%d",&z);
Out(z);
}
return 0;
}
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
分析: 如果可以将上一个 建立二叉堆的方法学会,这个题目应该很简单吧。就是模拟而已。
代码
#include<bits/stdc++.h>
using namespace std;
#define LL long long
/ / 数据应该是默认的 都是不一样的数字,不然同一个数字其位置不唯一,就不好玩了
const int N = 2e5+11;
const int M = 1e6+11;
const int mod = 1e9+7;
const int inf = 0x3f3f3f3f;
const LL inff = 0x3f3f3f3f3f3f3f3f;
int H[N],sz;
void Creat(){
H[0]=-inf;
sz=0;
}
void Insert(int x){
int i=++sz;
for(i;H[i/2]>x;i/=2) H[i]=H[i/2];
H[i]=x;
}
int Find(int x){ // 找到x在 一维数组中的位置pos,pos/2就是其父节点的标号
for(int i=1;i<=sz;i++){
if(H[i]==x) return i;
}
}
int main(){
Creat();
int n,m;scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
int x;scanf("%d",&x);
Insert(x);
}
while(m--){ // 我只能够说 其输入真恶心,我是一个字符串一个字符串判定分离的
int flag;
int a;scanf("%d",&a);
string x;cin>>x;
if(x=="and"){
int b;scanf("%d",&b);
string t; cin>>t; cin>>t;
a=Find(a); b=Find(b);
if(a/2 == b/2) flag=1;
else flag=0;
}else {
string y;cin>>y;
if(y=="a") {
string t; cin>>t; cin>>t;
int b;scanf("%d",&b);
a=Find(a) ; b=Find(b);
if(a/2 == b) flag=1;
else flag=0;
}else {
string z;cin>>z;
if(z=="root"){
if(H[1]==a) flag=1;
else flag=0;
}else {
string z;cin>>z;
int b;scanf("%d",&b);
a=Find(a) ;b=Find(b);
if(a==b/2) flag=1;
else flag=0;
}
}
}
if(flag) puts("T");
else puts("F");
}
return 0;
}