将一系列给定数字顺序插入一个初始为空的小顶堆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
思路:
先来一波概念~
小顶堆:是一种经过排序的完全二叉树(树的节点是按从上到下,从左到右的顺序紧凑排列的),其中任一非终端节点的数据值均不大于其左子节点和右子节点的值。
heap[i]:=位置i存的元素值。
若从heap[0]开始存,可知:
左儿子编号是自己编号*2+1
右儿子编号是自己编号*2+2
- 小顶堆插入数据时:
首先先在堆的末尾(在最后一层,最左边)插入该数值,然后不断向上提升至到它比父节点大为止。
- 小顶堆删除最小值时:
先把堆中最后一个元素复制到根节点,并且删除最后一个节点。然后不断向下交换直到没有大小点到为止。
若向下交换的时候,左右节点都小于此节点,则交换最小的节点。
模板:
void push(int x){
int i=sz++;
while(i>0){
int p=(i-1)/2;
if(heap[p]<=x)break;
heap[i]=heap[p];
i=p;
}
heap[i]=x;
}
int pop(){
int ret=heap[0];
int x=heap[--sz];
int i=0;
while(i*2+1<sz){//点i位置存在左子树即可,因为可能本来就不存在右子树
int c1=i*2+1,c2=i*2+2;
if(c2<sz&&heap[c1]>heap[c2])c1=c2;
if(heap[c1]>=x)break;
heap[i]=heap[c1];
i=c1;
}
heap[i]=x;
return ret;
}
ps:处理的时候,别忘了还有负数的情况哒~
代码如下:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<cstring>
#include<queue>
#include<stack>
#include<cmath>
#include<set>
#include<map>
using namespace std;
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
typedef pair<int,int>P;
const int INF=0x3f3f3f3f;
const int N=1005,N1=5005,mod=32767;
int heap[N],sz=0;
string s;
map<int,int>pos;
void push(int x){
int i=sz++;
while(i>0){
int p=(i-1)/2;
if(heap[p]<=x)break;
heap[i]=heap[p];
i=p;
}
heap[i]=x;
}
int getx(int po){
int x=0;
int tmp=1;
while(s[po]!=' '&&s[po]!='-'&&po>=0){
x+=(s[po]-'0')*tmp;
tmp*=10;
po--;
}
if(s[po]=='-')return -x;
return x;
}
int solve(){
int flag,len=s.length(),x=0,y=0;
for(int i=0;i<len;i++){
if(s[i]==' '){
x=getx(i-1);
if(s[i+1]=='a'){
flag=2;
y=getx(len-14);
}
else if(i+11==len-1)flag=1;
else if(s[i+4]=='t'){flag=3;y=getx(len-1);}
else if(s[i+4]=='a'){flag=4;y=getx(len-1);}
break;
}
}
if(flag==1){
if(heap[0]==x)return true;
else return false;
}
if(flag==2){
int p1=pos[x],p2=pos[y];
if(p1>p2)swap(p1,p2);
if(p1%2&&p2-p1==1)return true;
else return false;
}
if(flag==3){
int p1=pos[x],p2=pos[y];
if((p2-1)/2==p1)return true;
else return false;
}
if(flag==4){
int p1=pos[x],p2=pos[y];
if((p1-1)/2==p2)return true;
else return false;
}
}
int main(){
int n,m,t,x,y;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&t);
push(t);
}
for(int i=0;i<n;i++){
int x=heap[i];
pos.insert(pair<int,int>(x,i));
}
getchar();
while(m--){
getline(cin,s);
int ans=solve();
if(ans)printf("T\n");
else printf("F\n");
}
}