将一系列给定数字顺序插入一个初始为空的小顶堆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
- 这道题我就很偷懒的用了algorithm里的关于堆的函数了,没有自己写堆的构造部分。。
然后部分正确,有两个注意点
1.注意题目中说的是将一系列给定数字顺序插入一个初始为空的小顶堆H[]。
说明是没读入一个数字就要进行堆的调整的,并不是所有数字都输完之后再将向量调整成堆党的,这两种方式剑起来的堆是不一样的
2.判断是否是兄弟节点时,不仅仅要索引值相差1,大的哪个索引还必须是偶数才行
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <sstream>
using namespace std;
bool comp(int a, int b)
{
return a > b;
}
int main()
{
int n, m;
cin >> n >> m;
vector<int> nums;
for (int i = 0; i < n; ++i)
{
int x; cin >> x;
nums.push_back(x);
make_heap(nums.begin(), nums.end(), comp);
//每插入一个元素就调整一下堆
//而不是等所有元素输完了再调整成堆
//这两种方式最后形成的堆是有差别的
}
string cmd;
getline(cin, cmd);//把输数字那行的换行符读掉
for (int i = 0; i < m; ++i) {
getline(cin, cmd);
istringstream is(cmd);
if (i)
cout << endl;
string ts;
if (cmd.find("root") != string::npos) {
int x;
is >> x;
if (nums[0] == x)
cout << "T";
else
cout << "F";
}
if (cmd.find("siblings") != string::npos) {
int x, y;
is >> x;
is >> ts >> y;
int ix=n+1, iy=n+1;
//若只找到其中一个点则与另一个点的差绝对大于1
//若两个都没找到差就是0
for (int j = 0; j < n; ++j) {
if (nums[j] == x)
ix = j;
if (nums[j] == y)
iy = j;
if (ix != n + 1 && iy != n + 1)
break;
}
if (ix - iy == 1) {
if (ix % 2 == 0)
cout << "T";
else
cout << "F";
}
else if (iy - ix == 1) {
if (iy % 2 == 0)
cout << "T";
else
cout << "F";
}
else
cout << "F";
}
if (cmd.find("parent") != string::npos) {
int x, y;
is >> x;
is >> ts >> ts >> ts >> ts >> y;
int ix = n + 1, iy = n + 1;
//若只找到其中一个点则与另一个点的差绝对大于1
//若两个都没找到差就是0
for (int j = 0; j < n; ++j) {
if (nums[j] == x)
ix = j;
if (nums[j] == y)
iy = j;
if (ix != n + 1 && iy != n + 1)
break;
}
if (ix != n + 1 && iy != n + 1) {
//两个都找到了
if (iy == 2 * ix + 1 || iy == 2 * ix + 2)
cout << "T";
else
cout << "F";
}
else
cout << "F";
}
if (cmd.find("child") != string::npos) {
int x, y;
is >> x;
is >> ts >> ts >> ts >> ts >> y;
int ix = n + 1, iy = n + 1;
//若只找到其中一个点则与另一个点的差绝对大于1
//若两个都没找到差就是0
for (int j = 0; j < n; ++j) {
if (nums[j] == x)
ix = j;
if (nums[j] == y)
iy = j;
if (ix != n + 1 && iy != n + 1)
break;
}
if (ix != n + 1 && iy != n + 1) {
//两个都找到了
if (ix == 2 * iy + 1 || ix == 2 * iy + 2)
cout << "T";
else
cout << "F";
}
else
cout << "F";
}
}
system("pause");
return 0;
}