C4top-关于堆的判断 (最小堆)

关于堆的判断   

将一系列给定数字顺序插入一个初始为空的小顶堆H[]。随后判断一系列相关命题是否为真。命题分下列几种:

  • x is the rootx是根结点;
  • x and y are siblingsxy是兄弟结点;
  • x is the parent of yxy的父结点;
  • x is a child of yxy的一个子结点。

输入格式:

每组测试第1行包含2个正整数N\le 1000)和M\le 20),分别是插入元素的个数、以及需要判断的命题数。下一行给出区间[-10000, 10000][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
 
  • 时间限制:400ms
  • 内存限制:64MB
  • 代码长度限制:16kB
  • 判题程序:系统默认
  • 作者:陈越
  • 单位:浙江大学
题目判定
解题思路
用数组模拟一个最小堆,输入一个数就更新一次,不能输入完毕后一次性建堆。
根据每句话的特点分辨出要求的是什么,并分离出数值量。
父节点下标如果是i,则子节点下标是i*2+1和 i*2。
注意可能存在负数,如果用的一次读入一行含空格的字符穿,还需要吃掉第一行的回车符。
判断输入的代码巨丑……见谅(っ*´Д`)っ

解题程序
#include<cstdio>
#include<cstring>
#include<cmath>
#include<set>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
#define MAXN 200010
#define INF 0x3f3f3f3f
int heap[MAXN],sz=0;
int cmp(int a,int b)
{
    return a>b;
}
void push(int x)
{
    int i=++sz;
    while(i>1)
    {
        int p=i/2;//父亲节点的编号
        if(heap[p]<=x) break;//已经没有大小颠倒
        heap[i]=heap[p];//交换节点数值
        i=p;
    }
    heap[i]=x;
}

int pop()
{
    int ret=heap[0];
    int temp=sz;
    int x=heap[--temp];
    int i=0;
    while(i*2+1<temp)
    {
        int a=i*2+1,b=i*2+2;
        if(b<temp&&heap[b]<heap[a]) a=b;
        if(heap[a]>=x) break;
        heap[i]=heap[a];
        i=a;
    }
    heap[i]=x;
    return ret;
}
int main()
{
#ifdef ONLINE_JUDGE
#else
    freopen("G:/cbx/read.txt","r",stdin);
    //freopen("G:/cbx/out.txt","w",stdout);
#endif
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n,m;
    cin>>n>>m;
    for(int i=0; i<n; ++i)
    {
        int x;
        cin>>x;
        push(x);
    }
    int flag=-1;
    char s[100];
    cin.getline(s,100);// 吃掉回车符
    for(int i=0; i<m; ++i)
    {
        int a=0,b=0,pos,minu=1;
        cin.getline(s,100);
        //cout<<s<<endl;
        int len=strlen(s);
        if(s[len-1]=='t')//是根结点
        {
            flag=1;
            for(int j=0; j<len; ++j)
            {
                if(s[j]=='-')
                {
                    minu=-1;
                    continue;
                }
                a*=10;
                a+=int(s[j]-'0');
                if(s[j+1]==' ')
                {
                    a*=minu;
                    break;
                }
            }
        }
        else if(s[len-1]=='s')//是兄弟结点
        {
            flag=2;
            for(int j=0; j<len; ++j)
            {
                if(s[j]=='-')
                {
                    minu=-1;
                    continue;
                }
                a*=10;
                a+=int(s[j]-'0');
                if(s[j+1]==' ')
                {
                    a*=minu;
                    minu=1;
                    pos=j+6;
                    break;
                }
            }
            for(int j=pos; j<len; ++j)
            {
                if(s[j]=='-')
                {
                    minu=-1;
                    continue;
                }
                b*=10;
                b+=int(s[j]-'0');
                if(s[j+1]==' ')
                {
                    b*=minu;
                    break;
                }
            }
        }
        else
        {
            int cnt=0;
            for(int j=0; j<len; ++j)
            {
                if(s[j]==' ') ++cnt;
                if(cnt==2)
                {
                    if(s[j+1]=='t')
                    {
                        flag=3;//是父结点
                        for(int k=0; k<len; ++k)
                        {
                            if(s[k]=='-')
                            {
                                minu=-1;
                                continue;
                            }
                            a*=10;
                            a+=int(s[k]-'0');
                            if(s[k+1]==' ')
                            {
                                a*=minu;
                                minu=1;
                                pos=k+19;
                                break;
                            }
                        }
                        for(int k=pos; k<len; ++k)
                        {
                            if(s[k]=='-')
                            {
                                minu=-1;
                                continue;
                            }
                            b*=10;
                            b+=int(s[k]-'0');
                            if(s[k+1]=='\0')
                            {
                                b*=minu;
                                break;
                            }
                        }
                    }
                    else if(s[j+1]=='a')
                    {
                        flag=4;//是子结点
                        for(int k=0; k<len; ++k)
                        {
                            if(s[k]=='-')
                            {
                                minu=-1;
                                continue;
                            }
                            a*=10;
                            a+=int(s[k]-'0');
                            if(s[k+1]==' ')
                            {
                                a*=minu;
                                minu=1;
                                pos=k+16;
                                break;
                            }
                        }
                        for(int k=pos; k<len; ++k)
                        {
                            if(s[k]=='-')
                            {
                                minu=-1;
                                continue;
                            }
                            b*=10;
                            b+=int(s[k]-'0');
                            if(s[k+1]=='\0')
                            {
                                b*=minu;
                                break;
                            }
                        }
                    }
                    if(flag!=-1) break;
                }
            }
        }
        //cout<<a<<" "<<b<<endl;
        if(flag==1)//是根结点
        {
            if(heap[1]==a) cout<<"T"<<endl;
            else cout<<"F"<<endl;
        }
        else if(flag==2)//是兄弟结点
        {
            int j=0;
            for(int i=1; i<=n; ++i)
                if(heap[i]==a)
                {
                    j=i;
                    break;
                }
            j/=2;
            if(j!=0&&((heap[j*2]==a&&heap[j*2+1]==b)||(heap[j*2]==b&&heap[j*2+1]==a)))
                cout<<"T"<<endl;
            else cout<<"F"<<endl;
        }
        else if(flag==3)//是父结点
        {
            int j=0;
            for(int i=1; i<=n; ++i)
                if(heap[i]==a)
                {
                    j=i;
                    break;
                }
            if(j!=0&&((heap[j*2]==b||heap[j*2+1]==b)))
                cout<<"T"<<endl;
            else cout<<"F"<<endl;
        }
        else if(flag==4)//是子结点
        {
            int j=0;
            for(int i=1; i<=n; ++i)
                if(heap[i]==a)
                {
                    j=i;
                    break;
                }
            if(j!=0&&((heap[j/2]==b||heap[(j-1)/2]==b)))
                cout<<"T"<<endl;
            else cout<<"F"<<endl;
        }
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值