题目:
https://www.patest.cn/contests/gplt/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
思路:构造一个堆,然后相应的判断即可,插入堆时插入尾部然后进行调整。注意负数的问题。
#include <bits/stdc++.h> using namespace std; const int N = 1010; int n, m; int arr[N]; int solve(string s) //把字符串表示的数字转换成数字 { int sum = 0, i = 0; bool flag = false; if(s[0] == '-') flag = true, i = 1; //提取负号 for(; s[i]; i++) sum = sum * 10 + s[i] - '0'; if(flag) sum = -sum; //有负号的转换成负数 return sum; } int main() { int a; scanf("%d%d", &n, &m); int k = 0; for(int i = 0; i < n; i++) { scanf("%d", &a); arr[++k] = a; //插入堆的尾部,之后进行调整 int j = k; while(j > 1) { if(arr[j] < arr[j/2]) //比父节点小,就交换,持续到根节点 swap(arr[j], arr[j/2]), j /= 2; else break; } } getchar(); //注意,吃掉多余的回车 string s; int b, c; for(int i = 0; i < m; i++) { getline(cin, s); string str[10]; int len = 0; stringstream fin(s); while(fin >> str[len]) len++; //把所有的单词分离 if(len == 4) { b = solve(str[0]); if(b == arr[1]) printf("T\n"); //直接判断是不是根节点 else printf("F\n"); } else if(len == 5) { b = solve(str[0]), c = solve(str[2]); int flag = 0; for(int i = 1; i <= n; i++) if(arr[i] == b) { flag = i; break; } //找到任意一个数的位置求父节点,然后判断父节点的两个子节点 flag /= 2; if(flag != 0 && ((arr[flag*2] == b && arr[flag*2+1] == c) || (arr[flag*2] == c && arr[flag*2+1] == b))) printf("T\n"); else printf("F\n"); } else { b = solve(str[0]), c = solve(str[5]); if(str[3] == "parent") { int flag = 0; for(int i = 1; i <= n; i++) if(arr[i] == c) { flag = i; break; } //求父节点然后直接判断 if(arr[flag/2] == b) printf("T\n"); else printf("F\n"); } else if(str[3] == "child") { int flag = 0; for(int i = 1; i <= n; i++) if(arr[i] == b) { flag = i; break; } //求父节点然后直接判断 if(arr[flag/2] == c) printf("T\n"); else printf("F\n"); } } } return 0; }