L2-012 关于堆的判断(小顶堆)

L2-012 关于堆的判断 (25分)

将一系列给定数字顺序插入一个初始为空的小顶堆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

题解: 类似于线段树的存储方式,每加入一个值就从下往上更新。使用string的find函数进行解题会wa用char最原始的方式就ac了。

AC代码:

#include<string.h>
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<string>
#include<cstring>
#include<vector>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 1e3 + 10;
const int inf = 0x3f3f3f3f;
const int Base = 131;
const ll INF = 1ll << 62;
//const double PI = acos(-1);
const double eps = 1e-7;
const int mod = 1e9 + 9;
#define mem(a,b) memset(a,b,sizeof(a))
#define speed {ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); }
int Heap[maxn];
int n, m;
void buildheap(int deep) {//建立小顶堆
	int son = deep;
	int fa = deep >> 1;
	while (fa >= 1) {
		if (Heap[son] < Heap[fa]) {
			swap(Heap[fa], Heap[son]);
			son = fa;
			fa =fa>>1;
		}else {
			break;
		}
	}
}
int Search(int x) {//查询值的下标
	for (int i = 1; i <= n; i++) {
		if (Heap[i] == x) {
			return i;
		}
	}
}

int main() {

	scanf("%d %d",&n,&m);
	for (int i = 1; i <= n; i++) {
		scanf("%d",&Heap[i]);
		buildheap(i);
	}
	getchar();
	while(m--){
		int a, b;
		char s[50];
		scanf("%d %s",&a,s);
		if(s[0]=='a'){//判断是否是兄弟节点
			scanf("%d",&b);
			scanf("%s",s);
			scanf("%s",s);
			int p=Search(a)>>1;
			if(Heap[p<<1]==b||Heap[p<<1|1]==b)puts("T");
			else puts("F");
		}else{
			scanf("%s",s);
			scanf("%s",s);
			if(s[0]=='r'){//判断是否是根节点
				if(a==Heap[1])puts("T");
				else puts("F");
			}
			if(s[0]=='p'){//判断父亲节点
				scanf("%s",s);
				scanf("%d",&b);
				int p=Search(b)>>1;
				if(Heap[p]==a)puts("T");
				else puts("F");
			}
			if(s[0]=='c'){//判断子节点
				scanf("%s",s);
				scanf("%d",&b);
				int p=Search(a)>>1;
				if(Heap[p]==b)puts("T");
				else puts("F");
			}
		}
	}
	system("pause");
	return 0;
}

WA代码:

#include<string.h>
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<string>
#include<cstring>
#include<vector>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 1e3 + 10;
const int inf = 0x3f3f3f3f;
const int Base = 131;
const ll INF = 1ll << 62;
//const double PI = acos(-1);
const double eps = 1e-7;
const int mod = 1e9 + 9;
#define mem(a,b) memset(a,b,sizeof(a))
#define speed {ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); }

int Heap[maxn];
int n, m;
void buildheap(int deep) {
	int son = deep;
	int fa = deep >> 1;
	while (fa >= 1) {
		if (Heap[son] < Heap[fa]) {
			swap(Heap[fa], Heap[son]);
			son = fa;
			fa =fa>>1;
		}else {
			break;
		}
	}
}

int Search(int x) {
	for (int i = 1; i <= n; i++) {
		if (Heap[i] == x) {
			return i;
		}
	}
}

int main() {
	speed;
	scanf("%d %d",&n,&m);
	for (int i = 1; i <= n; i++) {
		scanf("%d",&Heap[i]);
		buildheap(i);
	}
	getchar();
	while(m--){
		int a, b;
		string s;
		getline(cin,s);
		if (s.find("root") != s.npos) {
			sscanf(s.c_str(), "%d is the root", &a);
			if (a == Heap[1])puts("T");
			else puts("F");
			continue;
		}
		if (s.find("siblings") != s.npos) {
			sscanf(s.c_str(), "%d and %d are siblings", &a, &b);
			int fapos = Search(a)>>1;
			if (b == Heap[fapos << 1] || b == Heap[fapos << 1 | 1])puts("T");
			else puts("F");
			continue;
		}
		if (s.find("parent") != s.npos) {
			sscanf(s.c_str(), "%d is the parent of %d", &a, &b);
			int fapos = Search(b)>>1;
			if (a == Heap[fapos])puts("T");
			else puts("F");
			continue;
		}
		if (s.find("child") != s.npos) {
			sscanf(s.c_str(), "%d is a child of %d", &a, &b);
			int fapos = Search(a)>>1;
			if (b == Heap[fapos])puts("T");
			else puts("F");
			continue;
		}
	}
	system("pause");
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值