【天梯赛-初赛题】L2-004 关于堆的判断
2016-06-06 21:03
471 查看
题目:
将一系列给定数字顺序插入一个初始为空的小顶堆H[]。随后判断一系列相关命题是否为真。命题分下列几种:
输入格式:
每组测试第1行包含2个正整数N(<= 1000)和M(<= 20),分别是插入元素的个数、以及需要判断的命题数。下一行给出区间[-10000, 10000]内的N个要被插入一个初始为空的小顶堆的整数。之后M行,每行给出一个命题。题目保证命题中的结点键值都是存在的。
输出格式:
对输入的每个命题,如果其为真,则在一行中输出“T”,否则输出“F”。
比赛的时候没来得及看题,赛后做了下,发现了自身不少问题。
题目很简单,只要小根堆建好了就没有问题。一开始选择了先输入所有,最后建堆,一连改了13次都没成功;改为边输入边建堆就没问题了。其实,边输入边建堆和统一建堆最后的顺序是不一样的。
代码1-统一建堆:
代码2-边输入边建堆:
将一系列给定数字顺序插入一个初始为空的小顶堆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”。
比赛的时候没来得及看题,赛后做了下,发现了自身不少问题。
题目很简单,只要小根堆建好了就没有问题。一开始选择了先输入所有,最后建堆,一连改了13次都没成功;改为边输入边建堆就没问题了。其实,边输入边建堆和统一建堆最后的顺序是不一样的。
代码1-统一建堆:
#include<stdio.h> int a[1010]; int index[20100]; char s1[30],s2[30],s3[30],s4[30]; void sift(int i,int n) { int j; int pos; int t = a[i]; pos = i; j = 2*i; while(j<=n) { if(j<n && a[j] > a[j+1]) j=j+1; if(t <= a[j]) break; else { a[pos] = a[j]; index[a[pos]+10005] = pos; pos = j; j = 2*j; } } a[pos] = t; index[t+10005] = pos; } int main() { int n,m; int i; int j; int num1,num2; scanf("%d%d",&n,&m); for(i=1;i<=n;i++) { scanf("%d",&a[i]); index[a[i]+10005] = i; } for(i=n/2;i>=1;i--) { sift(i,n); } for(i=0;i<m;i++) { scanf("%d%s",&num1,s1); if(s1[0] == 'a') { scanf("%d%s%s",&num2,s2,s3); printf("%c\n", (index[num1+10005]/2 == index[num2+10005]/2 && index[num1+10005] != 0 && index[num2+10005] != 0) ? 'T' : 'F' ); } else { scanf("%s%s",s2,s3); if(s3[0] == 'r') { printf("%c\n", (index[num1+10005] == 1) ? 'T' : 'F' ); } else if(s3[0] == 'p') { scanf("%s%d",s4,&num2); printf("%c\n", (index[num1+10005] == index[num2+10005] / 2 && index[num1+10005] != 0 && index[num2+10005] != 0) ? 'T' : 'F' ); } else if(s3[0] == 'c') { scanf("%s%d",s4,&num2); printf("%c\n", (index[num2+10005] == index[num1+10005] / 2 && index[num1+10005] != 0 && index[num2+10005] != 0) ? 'T' : 'F' ); } } } return 0; }
代码2-边输入边建堆:
#include<stdio.h> int a[1010]; int index[20100]; char s1[30],s2[30],s3[30],s4[30]; void sift(int i) { if(i == 1) return; int pos = i/2; if(a[i] < a[pos]) { int t = a[i]; a[i] = a[pos]; a[pos] = t; index[a[i]+10005] = i; index[a[pos] +10005] = pos; sift(pos); } } int main() { int n,m; int i; int j; int num1,num2; scanf("%d%d",&n,&m); for(i=1;i<=n;i++) { scanf("%d",&a[i]); index[a[i]+10005] = i; sift(i); } for(i=0;i<m;i++) { scanf("%d%s",&num1,s1); if(s1[0] == 'a') { scanf("%d%s%s",&num2,s2,s3); printf("%c\n", (index[num1+10005]/2 == index[num2+10005]/2 && index[num1+10005] != 0 && index[num2+10005] != 0) ? 'T' : 'F' ); } else { scanf("%s%s",s2,s3); if(s3[0] == 'r') { printf("%c\n", (index[num1+10005] == 1) ? 'T' : 'F' ); } else if(s3[0] == 'p') { scanf("%s%d",s4,&num2); printf("%c\n", (index[num1+10005] == index[num2+10005] / 2 && index[num1+10005] != 0 && index[num2+10005] != 0) ? 'T' : 'F' ); } else if(s3[0] == 'c') { scanf("%s%d",s4,&num2); printf("%c\n", (index[num2+10005] == index[num1+10005] / 2 && index[num1+10005] != 0 && index[num2+10005] != 0) ? 'T' : 'F' ); } } } return 0; }
相关文章推荐
- 如何组织构建多文件 C 语言程序(二)
- 如何写好 C main 函数
- Lua和C语言的交互详解
- 关于C语言中参数的传值问题
- 简要对比C语言中三个用于退出进程的函数
- 深入C++中API的问题详解
- 基于C语言string函数的详解
- C语言中fchdir()函数和rewinddir()函数的使用详解
- C语言内存对齐实例详解
- C语言编程中统计输入的行数以及单词个数的方法
- C语言自动生成enum值和名字映射代码
- C语言练习题:自由落体的小球简单实例
- 使用C语言判断英文字符大小写的方法
- c语言实现的带通配符匹配算法
- C语言实现顺序表基本操作汇总
- C语言中进制知识汇总
- C语言判断一个数是否是2的幂次方或4的幂次方
- C语言中计算正弦的相关函数总结
- 使用C语言详解霍夫曼树数据结构
- C语言实现选择排序、冒泡排序和快速排序的代码示例