【无标题】

题目名字

[题目链接]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;
		}
	}
}
 
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值