将一系列给定数字顺序插入一个初始为空的小顶堆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>
#define INF 0x3f3f3f3f
using namespace std;
int n,m;
int h[1001];
void shifdown(int i)
{
int flag=0;
int t=i;
while(2*i<=n&&!flag)
{
if(h[2*i]<h[i])
{
t=2*i;
}
if(2*i+1<=n)
{
if(h[t]>h[2*i+1])
{
t=2*i+1;
}
}
if(t!=i)
{
swap(h[t],h[i]);
i=t;
}
else
{
flag=1;
}
}
}
void creat()
{
int i;
for(i=n/2; i>=1; i--)
{
shifdown(i);
}
return;
}
int Find(int x)
{
for(int i=1; i<=n; i++)
{
if(h[i]==x)
{
return i;
}
}
return -1;
}
int size;
//int tree[1001];
int main()
{
cin>>n>>m;
h[0]=-999999;
for(int i=1; i<=n; i++)
{
int key;
cin>>key;
int j=++size;
for(;h[j/2]>key;j/=2)
{
h[j]=h[j/2];
}
h[j]=key;
}
/*
for(int i=1;i<=n;i++)
{
cin>>tree[i];
}
create();*/
while(m--)
{
int num1;
cin>>num1;
getchar();
string s1;
cin>>s1;
if(s1=="and")
{
int num2;
cin>>num2;
string s2,s3;
cin>>s2;
cin>>s3;
int x1=Find(num1);
int y1=Find(num2);
if(x1==-1||y1==-1)
{
cout<<"F"<<endl;
}
else
{
if(x1/2==y1/2)
{
cout<<"T"<<endl;
}
else
{
cout<<"F"<<endl;
}
}
}
else
{
string s2;
cin>>s2;
if(s2=="a")
{
string s3;
cin>>s3;
string s4;
cin>>s4;
int num2;
cin>>num2;
int x1=Find(num1);
if(x1==-1)
{
cout<<"F"<<endl;
}
else
{
if(h[x1/2]==num2)
{
cout<<"T"<<endl;
}
else
{
cout<<"F"<<endl;
}
}
}
else
{
string s3;
cin>>s3;
if(s3=="root")
{
if(num1==h[1])
{
cout<<"T"<<endl;
}
else
{
cout<<"F"<<endl;
}
}
else
{
string s4;
cin>>s4;
int num2;
cin>>num2;
int x1=Find(num2);
if(x1==-1)
{
cout<<"F"<<endl;
}
else
{
if(h[Find(num2)/2]==num1)
{
cout<<"T"<<endl;
}
else
{
cout<<"F"<<endl;
}
}
}
}
}
}
return 0;
}