题目:关于堆的判断
题意:建最小堆,输入语句查询是否正确~
思路:
(1)建堆:直接建堆模板,但是这里要用向上调整,因为每次是插入一个元素(我开始用向下的错了。。。)
(2)建堆后每个值都按顺序存储到了数组下,此时利用一个map集合将值与下标翻转过来(互换);
(3)输入处理,注意负数,然后找相应的关系输出即可。
根:下标为1
兄弟:下标相差1且同根
x为y的父节点:y下标/2 == x下标
x为y的子节点:x下标/2 == y下标
参考:柳婼博客
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;
const int maxn = 1005;
int h[maxn],n;
map<int,int>mp;
void siftup(int i){//向上调整
int flag = 0;
if(i == 1) return;
while(i != 1 && !flag){
if(h[i] < h[i/2]) swap(h[i],h[i/2]);
else flag = 1;
i /= 2;
}
}
int main()
{
int m;
char str[100];
while(~scanf("%d%d",&n,&m)){
for(int i=1;i<=n;i++) {scanf("%d",&h[i]);siftup(i);}getchar();
mp.clear();
for(int i=1;i<=n;i++) mp[h[i]] = i;//将值与下标对调
for(int i=0;i<m;i++){
gets(str);
int k = 0,u = 0,v = 0,len = strlen(str);
if(str[k] == '-') k++;//负数情况
while(str[k] >= '0' && str[k] <= '9') {u *= 10;u += (str[k] - '0');k++;}
if(str[0] == '-') u = -u;//负数
while(str[k] < '0' || str[k] > '9') k++;
int record = k-1;
while(str[k] >= '0' && str[k] <= '9' && k < len ) {v *= 10;v += (str[k] - '0');k++;}
if(str[record] == '-') v = -v;//负数
if(str[len - 1] == 't'){//根
if(mp[u] == 1) printf("T\n");else printf("F\n");//第一个位置即为根
}
else if(str[len-1] == 's'){//兄弟
if(abs(mp[u] - mp[v]) == 1 && mp[u]/2 == mp[v]/2) printf("T\n");else printf("F\n");//当下标差1 且同为一个根
}
else{
int flag = 0;
for(int j=0;j<len;j++)
if(str[j] == 'c'){flag = 1;break;}
if(flag){//x是y的一个子结点
if(mp[u]/2 == mp[v]) printf("T\n");else printf("F\n");
}else{//x是y的父结点;
if(mp[v]/2 == mp[u]) printf("T\n");else printf("F\n");
}
}
}
}
return 0;
}