题目名字
[题目链接]https://pintia.cn/problem-sets/994805046380707840/problems/994805064676261888
题意
将一系列给定数字顺序插入一个初始为空的小顶堆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.剩下三种情况,都需取两个数字)
在小顶堆数组中查找上一步提取的数字下标。
根据小顶堆数组下标规则判断是否正确。
代码
#include <string>
#include <cmath>
using namespace std;
int parent(int n)//修改数组下标
{
return (n-1)/2;
}
void buildHeap(int n , int data[])//建立小顶堆
{
for(int i= 1; i < n ; i++)
{
int t = i;
while( t != 0 && data[parent(t)] > data[t])
{
int temp = data[t];
data[t] = data[parent(t)];
data[parent(t)] = temp;
t = parent(t);
}
}
}
int main()
{
int data[1000],n,m;
string s;
cin>>n>>m;
for(int i=0;i<n;i++)
cin>>data[i];
buildHeap(n,data);
for(int i=0;i<m;i++)
{
if(i==0)
getchar();
getline(cin,s);
if(s.find("root")<s.length())//判断是否是根节点
{
int num=0;
bool f=0;
for(int j=0;j<6;j++)//因为整数在[-10000,10000]中,故加上负号最多处理六位
if(s[j]-'0'>=0&&s[j]-'0'<=9)
num=num*10+s[j]-'0';
else if(s[j]=='-')//若有负号则f=1
f=1;
else
break;
if(f)//若f=1,数字为负,则num取反
num=-num;
if(data[0]==num)
cout<<"T"<<endl;
else
cout<<"F"<<endl;
}
else //判断是否是兄弟节点/父节点/子节点
{
int num1=0,num2=0,m1=-1,m2=-1,j;
bool f=0;
for(j=0;j<6;j++)
if(s[j]-'0'>=0&&s[j]-'0'<=9)
num1=num1*10+s[j]-'0';
else if(s[j]=='-')//若有负号则f=1
f=1;
else
break;
if(f)//如果有负号则num1取反
num1=-num1;
f=0;
if(s.find("parent")<s.length())//处理parent情况
for(int k=j+18;k<j+24;k++)
if(s[k]-'0'>=0&&s[k]-'0'<=9)
num2=num2*10+s[k]-'0';
else if(s[k]=='-')
f=1;
else
break;
else if(s.find("child")<s.length())//处理child情况
for(int k=j+15;k<j+21;k++)
if(s[k]-'0'>=0&&s[k]-'0'<=9)
num2=num2*10+s[k]-'0';
else if(s[k]=='-')
f=1;
else
break;
else
for(int k=j+5;k<j+10;k++)//处理是否兄弟节点情况
if(s[k]-'0'>=0&&s[k]-'0'<=9)
num2=num2*10+s[k]-'0';
else if(s[k]=='-')
f=1;
else
break;
if(f)//如果有负号则num2取反
num2=-num2;
for(int j=0;j<n;j++)//求两个数在小顶堆数组中的下标
if(data[j]==num1)
m1=j;
else if(data[j]==num2)
m2=j;
//cout<<m1<<m2;
if((m1-1)/2==m2&&s.find("child")<s.length())//判断num1是否是num2孩子
cout<<"T"<<endl;
else if((m2-1)/2==m1&&s.find("parent")<s.length())//判断num1是否是num1父节点
cout<<"T"<<endl;
else if(abs(m1-m2)==1&&(m2-1)/2==(m1-1)/2&&s.find("siblings")<s.length())//判断是否是兄弟节点
cout<<"T"<<endl;
else//三种情况都不是
cout<<"F"<<endl;
}
}
}