天梯赛 L2-012 关于堆的判断 (二叉树)
将一系列给定数字顺序插入一个初始为空的小顶堆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
分析:
所谓小顶堆就是要求对于树中的每一个根节点来说,即小于他的左子树又小于他的右子树。
我们首先要将输入的序列构造成一个小顶堆,在这个构造的过程中应该注意的一点就是不能够在把树构造完成之后再进行调整,而是应该每当插入一个节点的时候就将树的结构调整好,这里应该注意调整的方法,因为如果你调整的方法不一样的话所构造出来的小顶堆的形式也是不一样的,这样对我们后期数据的判断会有很大的影响。
如果是树的形态构造好之后再进行调整的话,我们应该明确一点就是对于叶子节点来书是不需要进行调整的,所以开始调整的点的下标就应该是n=N/2。
void Tiao(int n)
{
	int temp;
	for(int i=n;i>0;i--)//从第一个节点开始往前调整
	{
		int t=i,op=0;
		while( i*2<=N&&op==0)//有左孩子,并且这个节点没有达到平衡状态
		{
			if(i*2<=N)
				if(a[i]>a[i*2])//有左节点且根节点小于左节点
				{
					t=2*i;
				}
			if(i*2+1<=N)
				if(a[t]>a[i*2+1])//有右节点,且右节点小于左节点和根节点中的较小值
				{
					t=2*i+1;
				}
			if(t!=i)//相当于当前的树形式需要进行调整
			{
				temp=a[i];
				a[i]=a[t];
				a[t]=temp;
				i=t;
			}
			else//不用调整的话,就不用再往下了,
			op=1;
		}
	}
}
但是这种调整的方法并不适合我们的题目,题目要求我们每次插入一个节点之后就要进行调整
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std;
int N,M;
int a[10000];
void just(int n)
{
    int i=n;
    int temp;
    if(i==1)//第一个相当于整个树的根节点,是不用进行调整的
        return;
    else
    {
        while(i!=1)//插入的当前结点要与他的根结点进行比较
        {
            if(a[i]<a[i/2])
            {
                temp=a[i];
                a[i]=a[i/2];
                a[i/2]=temp;
                i=i/2;
            }
            else
                break;
        }
    }
}
int main()
{
    scanf("%d%d",&N,&M);
    for(int i=1; i<=N; i++)
    {
        scanf("%d",&a[i]);//每次加入一个节点都要进行调整
        just(i);
    }
    getchar();
    for(int kk=1; kk<=M; kk++)
    {
        char s[1000];
        string ss;
        gets(s);
        ss=s;
        int op;
        op=ss.find("root");//find()方法是string类型下的方法 ,返回的是找到的第一个字符的下标
        if(op!=-1)//相当于找到了
        {
            int mm;
            sscanf(s,"%d",&mm);//输入流,把s的第一个整形数据给mm
            if(a[1]==mm)//为根节点
                printf("T\n");
            else
                printf("F\n");
        }
        else//没有找到
        {
            op=ss.find("siblings");
            if(op!=-1)
            {
                int mm,nn,n,m;
                char ch1[10];
                sscanf(s,"%d %s %d",&nn,ch1,&mm);
                for(int i=1; i<=N; i++)
                {
                    if(a[i]==nn)
                        n=i;
                    if(a[i]==mm)
                        m=i;
                }
                if(n/2==m/2)
                    printf("T\n");
                else
                    printf("F\n");
            }
            else
            {
                op=ss.find("parent");
                if(op!=-1)
                {
                    int mm,nn,m,n;
                    char ch1[10];
                    char ch2[10];
                    char ch3[10];
                    char ch4[10];
                    sscanf(s,"%d %s %s %s %s %d",&nn,ch1,ch2,ch3,ch4,&mm);
                    for(int i=1; i<=N; i++)
                    {
                        if(a[i]==nn)
                            n=i;
                        if(a[i]==mm)
                            m=i;
                    }
                    if(n==m/2)
                        printf("T\n");
                    else
                        printf("F\n");
                }
                else
                {
                    op=ss.find("child");
                    if(op!=-1)
                    {
                        int mm,nn,n,m;
                        char ch1[10];
                        char ch2[10];
                        char ch3[10];
                        char ch4[10];
                        sscanf(s,"%d %s %s %s %s %d",&nn,ch1,ch2,ch3,ch4,&mm);
                        //这里虽然中间的字符串没有用到,也要获取出来,不然没法取到最后一个整形数据
						for(int i=1; i<=N; i++)
                        {
                            if(a[i]==nn)
                                n=i;
                            if(a[i]==mm)
                                m=i;
                        }
                        if( n/2==m)
                            printf("T\n");
                        else
                            printf("F\n");
                    }
                }
            }
        }
    }
    return 0;
}天梯赛 L2-012 关于堆的判断 (二叉树)的更多相关文章
- PTA天梯赛L2
		L2-001 紧急救援 题意:就是给你一张n<500的图:让你求最短路径,最短路条数,以及路径: 做法,先用dijkstra求最短路,然后dfs找最短路条数,以及点权的最大值: 一般dfs不就可 ... 
- pat 团体天梯赛 L2-012. 关于堆的判断
		L2-012. 关于堆的判断 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 将一系列给定数字顺序插入一个初始为空的小顶堆H[] ... 
- PTA|团体程序设计天梯赛-练习题目题解锦集(C/C++)(持续更新中……)
		PTA|团体程序设计天梯赛-练习题目题解锦集(持续更新中) 实现语言:C/C++: 欢迎各位看官交流讨论.指导题解错误:或者分享更快的方法!! 题目链接:https://pintia.cn/ ... 
- L1-049 天梯赛座位分配
		L1-049 天梯赛座位分配 (20 分) 天梯赛每年有大量参赛队员,要保证同一所学校的所有队员都不能相邻,分配座位就成为一件比较麻烦的事情.为此我们制定如下策略:假设某赛场有 N 所学校参赛,第 i ... 
- 第四届CCCC团体程序设计天梯赛 后记
		一不小心又翻车了,第二次痛失200分 1.开局7分钟A了L2-3,一看榜已经有七个大兄弟排在前面了,翻车 * 1 2.把L1-3 A了18分,留了两分准备抢顽强拼搏奖,最后五秒钟把题过了,万万没想到还 ... 
- 团体程序设计天梯赛(CCCC) L3009 长城 方法证明
		团体程序设计天梯赛代码.体现代码技巧,比赛技巧. https://github.com/congmingyige/cccc_code 
- L1-049. 天梯赛座位分配
		天梯赛每年有大量参赛队员,要保证同一所学校的所有队员都不能相邻,分配座位就成为一件比较麻烦的事情.为此我们制定如下策略:假设某赛场有 N 所学校参赛,第 i 所学校有 M[i] 支队伍,每队 10 位 ... 
- 天梯赛2016-L2
		L2-001. 紧急救援 作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图.在地图上显示有多个分散的城市和一些连接城市的快速道路.每个城市的救援队数量和每一条连接两个城市的快速道路长度都标在 ... 
- 『ACM C++』 PTA 天梯赛练习集L1 | 052-053
		今日刷题,水题水题 ------------------------------------------------L1-052------------------------------------ ... 
- PTA  L2-023 图着色问题-前向星建图 团体程序设计天梯赛-练习集
		L2-023 图着色问题 (25 分) 图着色问题是一个著名的NP完全问题.给定无向图,,问可否用K种颜色为V中的每一个顶点分配一种颜色,使得不会有两个相邻顶点具有同一种颜色? 但本题并不是要你解 ... 
随机推荐
- TCP建立连接和断开连接过程
			假设Client端发起中断连接请求,也就是发送FIN报文.Server端接到FIN报文后,意思是说"我Client端没有数据要发给你了",但是如果你还有数据没有发送完成,则不必急着 ... 
- Spring AOP基础
			目录 AOP基本术语 Advice-通知 Before After After-returning After-throwing Around Pointcut-切点 Aspect-切面 Join P ... 
- Simple上网导航--静态版
			现在的网址导航显然是一个针对小白用户的网页大全,新闻.笑话.视频.黄段子要什么有什么,一个网址导航竟然也要滑动好多页.其实80%的功能我都用不到,但是它们却时刻展现在我的眼前.所以我决定做一个简洁清晰 ... 
- (一)Quartz2.2.1 简单例子
			转载至http://blog.csdn.net/a4307515/article/details/46985533 1.关键接口 Scheduler,任务调度的API:它可以用来启动或者终止任务等. ... 
- 洛谷 P1987 摇钱树
			题目戳 题目描述 Cpg 正在游览一个梦中之城,在这个城市中有n棵摇钱树...这下,可让Cpg看傻了...可是Cpg只能在这个城市中呆K天,但是现在摇钱树已经成熟了,每天每棵都会掉下不同的金币(不属于 ... 
- 基于注解的spring mvc 中使用 ajax json 的model
			在 Spring mvc3中,响应.接受 JSON都十分方便. 使用注解@ResponseBody可以将结果(一个包含字符串和JavaBean的Map),转换成JSON. 使用 @RequestBod ... 
- BZOJ4070 [Apio2015]雅加达的摩天楼  【分块 + 最短路】
			题目链接 BZOJ4070 题解 考虑暴力建图,将每个\(B_i\)向其能到的点连边,复杂度\(O(\sum \frac{n}{p_i})\),当\(p\)比较小时不适用 考虑优化建图,每个\(dog ... 
- linux 进程信号集合 sigset_t
			sigset_t 号集及信号集操作函数:信号集被定义为一种数据类型: typedef struct { unsigned long sig[_NSIG_WORDS]: } sigset_t 信号集用来 ... 
- Oracle中rank() over, dense_rank(), row_number() 的区别
			摘自:http://www.linuxidc.com/Linux/2015-04/116349.htm Oracle 中 rank() over, dense_rank(), row_number() ... 
- JS中如何使用EL表达式中的对象
			JS中如何使用EL表达式中的对象 2017年09月25日 15:33:09 lhpnba 阅读数:4859 1.js中使用el表达式要加双引号或单引号:'${list}' 2.js变量获取el表达 ... 
