GPLT L2-012. 关于堆的判断【建堆】

题目:关于堆的判断

题意:建最小堆,输入语句查询是否正确~

思路:

(1)建堆:直接建堆模板,但是这里要用向上调整,因为每次是插入一个元素(我开始用向下的错了。。。)

(2)建堆后每个值都按顺序存储到了数组下,此时利用一个map集合将值与下标翻转过来(互换);

(3)输入处理,注意负数,然后找相应的关系输出即可。

根:下标为1

兄弟:下标相差1且同根

x为y的父节点:y下标/2 == x下标

x为y的子节点:x下标/2 == y下标

参考:柳婼博客

代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;
const int maxn = 1005;
int h[maxn],n;
map<int,int>mp;
void siftup(int i){//向上调整
    int flag = 0;
    if(i == 1) return;
    while(i != 1 && !flag){
        if(h[i] < h[i/2]) swap(h[i],h[i/2]);
        else flag = 1;
        i /= 2;
    }
}
int main()
{
    int m;
    char str[100];
    while(~scanf("%d%d",&n,&m)){
        for(int i=1;i<=n;i++) {scanf("%d",&h[i]);siftup(i);}getchar();
        mp.clear();
        for(int i=1;i<=n;i++) mp[h[i]] = i;//将值与下标对调
        for(int i=0;i<m;i++){
            gets(str);
            int k = 0,u = 0,v = 0,len = strlen(str);
            if(str[k] == '-') k++;//负数情况
            while(str[k] >= '0' && str[k] <= '9') {u *= 10;u += (str[k] - '0');k++;}
            if(str[0] == '-') u = -u;//负数
            while(str[k] < '0' || str[k] > '9') k++;
            int record = k-1;
            while(str[k] >= '0' && str[k] <= '9' && k < len ) {v *= 10;v += (str[k] - '0');k++;}
            if(str[record] == '-') v = -v;//负数
            if(str[len - 1] == 't'){//根
                if(mp[u] == 1) printf("T\n");else printf("F\n");//第一个位置即为根
            }
            else if(str[len-1] == 's'){//兄弟
                if(abs(mp[u] - mp[v]) == 1 && mp[u]/2 == mp[v]/2) printf("T\n");else printf("F\n");//当下标差1 且同为一个根
            }
            else{
                int flag = 0;
                for(int j=0;j<len;j++)
                    if(str[j] == 'c'){flag = 1;break;}
                if(flag){//x是y的一个子结点
                    if(mp[u]/2 == mp[v]) printf("T\n");else printf("F\n");
                }else{//x是y的父结点;
                    if(mp[v]/2 == mp[u]) printf("T\n");else printf("F\n");
                }
            }
        }
    }
    return 0;
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值