将一系列给定数字顺序插入一个初始为空的小顶堆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
。
输入样例:
1. 5 4 2. 46 23 26 24 10 3. 24 is the root 4. 26 and 23 are siblings 5. 46 is the parent of 23 6. 23 is a child of 10
结尾无空行
输出样例:
1. F 2. T 3. F 4. T
结尾无空行
思路:把堆存入数组之中,i的左孩子为2*i,右孩子为2*i+1,用x1来表示x的下标,用y1来表示y的下标,x是根结点等价于x==h[1],x和y是兄弟结点等价于和x和y具有相同的父节点,即:h[x1/2]==h[y1/2],x是y的父结点等价于h[x1]==h[y1/2],x是y的一个子结点等价于h[x1/2]==h[y1]
#include<iostream> using namespace std; const int N=1010; int main() { int n,h[N],m; cin>>n>>m; for(int i=1;i<=n;i++) cin>>h[i]; for(int i=1;i<=n;i++)//建立小根堆 { int k=i; while(k>1&&h[k]<h[k/2]) { swap(h[k],h[k/2]); k/=2; } } while(m--) { int x,y,x1,y1; string s1,s2,s3,s4; cin>>x>>s1; if(s1=="and") { cin>>y>>s2>>s3; for(int i=1;i<=n;i++) { if(h[i]==x) x1=i; if(h[i]==y) y1=i;//找到对应的下标 } if(h[x1/2]==h[y1/2]) cout<<"T\n"; else cout<<"F\n"; } else { cin>>s2; if(s2=="a") { cin>>s3>>s4>>y; for(int i=1;i<=n;i++) { if(h[i]==x) x1=i; if(h[i]==y) y1=i;//找到对应的下标 } if(h[x1/2]==h[y1]) cout<<"T\n"; else cout<<"F\n"; } else { cin>>s3; if(s3=="root") { if(x==h[1]) cout<<"T\n"; else cout<<"F\n"; } else { cin>>s4>>y; for(int i=1;i<=n;i++) { if(h[i]==x) x1=i; if(h[i]==y) y1=i;//找到对应的下标 } if(h[x1]==h[y1/2]) cout<<"T\n"; else cout<<"F\n"; } } } } return 0; }