关于堆的判断
时间限制: 400 ms
内存限制: 64 MB
将一系列给定数字顺序插入一个初始为空的小顶堆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。
输入样例:
1 2 3 4 5 6
| 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
|
输出样例:
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
| #include <stdio.h>
int H[1005], ind[20005];
void adj(int start, int end) { int rc = H[start]; int s = start; for(int j = start * 2; j <= end; j *= 2) { if(j < end && H[j+1] < H[j]) j++; if(rc > H[j]) { H[s] = H[j]; s = j; } else break; } H[s] = rc; return; }
int main() { int n, m; scanf("%d%d", &n, &m); for(int i = 0; i < n; ++i) { scanf("%d", &H[i+1]); for(int j = (i+1)/2; j > 0; --j) adj(j, i+1); } for(int i = 0; i < n; ++i) ind[H[i+1] + 10000] = i+1; int a, b, ans = 0; char comm[10]; while(m--) { ans = 0; scanf("%d%s", &a, comm); if(comm[0] == 'a') { scanf("%d%*s%*s", &b); if(ind[a + 10000] / 2 == ind[b + 10000] / 2) ans = 1; } else { scanf("%s", comm); if(comm[0] == 'a') { scanf("%*s%*s%d", &b); if(ind[a + 10000] / 2 == ind[b + 10000]) ans = 1; } else { scanf("%s", comm); if(comm[0] == 'r') { if(ind[a + 10000] == 1) ans = 1; } else { scanf("%*s%d", &b); if(ind[b + 10000] / 2 == ind[a + 10000]) ans = 1; } } } printf("%c\n", ans ? 'T' : 'F'); } return 0; }
|