7-27 关于堆的判断 (25 分)
将一系列给定数字顺序插入一个初始为空的小顶堆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<cstdio>
#include<iostream>
using namespace std;
const int mindata=-999999999;
int N,M,x;
typedef struct HNode *Heap;
struct HNode{
int *Data;
int size;
int Capacity;
};
typedef Heap MinHeap;//最小堆
MinHeap CreatHeap(int maxsize){ //最小堆的创建
//创建容量为maxsize的空的最小堆
MinHeap H=new HNode;
H->Data=new int[maxsize+1];
H->size=0;
H->Capacity=maxsize;
H->Data[0]=mindata;//定义“哨兵”为小于堆中所有可能元素的值
return H;
}
bool isfull(MinHeap H){
return (H->size==H->Capacity);
}
bool insert(MinHeap H,int X){// 最小堆的插入
int i;
if(isfull(H)){
return false;
}
i=++H->size;//i指向插入后堆中的最后一个元素的位置
for(;H->Data[i/2]>X;i/=2)
H->Data[i]=H->Data[i/2];//上滤
H->Data[i]=X;//将x插入
return true;
}
int find(MinHeap H,int x){
int pos;
for(int i=1;i<=N;i++){
if(H->Data[i]==x){
pos=i;
break;
}
}
return H->Data[pos>>1];
}
int main(){
scanf("%d%d",&N,&M);
MinHeap H=CreatHeap(N);
for(int i=0;i<N;i++){
scanf("%d",&x);
insert(H,x);
}
for(int i=0;i<M;i++){
int x,y;
string s1,s2,s3;
cin>>x>>s1;
if(s1=="and"){ //x and y are siblings:x和y是兄弟结点;
cin>>y>>s2>>s3;
if(find(H,x)==find(H,y))
printf("T\n");
else
printf("F\n");
continue;
}
cin>>s1;
if(s1=="a"){ //x is a child of y:x是y的一个子结点。
cin>>s2>>s3>>y;
if(find(H,x)==y)
printf("T\n");
else
printf("F\n");
continue;
}
cin>>s1;
if(s1=="root"){ //x is the root:x是根结点;
if(find(H,x)==mindata)
printf("T\n");
else
printf("F\n");
continue;
}
cin>>s1>>y; //x is the parent of y:x是y的父结点;
if(find(H,y)==x)
printf("T\n");
else
printf("F\n");
}
return 0;
}