关于堆的判断 (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
//此题有点坑 //开始利用先输入所有数据再建堆,两个测试点没过 //改成边输入边上滤建堆,对了...... #include <cstdio> #include <cstring> #include <cstdlib> #include <cctype> #include <iostream> using namespace std; int n,heap[1005]; void PrecUp(int loc){ int i,temp=heap[loc]; for(i=loc;i>1&&heap[i/2]>temp;i/=2){ heap[i]=heap[i/2]; } heap[i]=temp; return; } void Deal(int &x,int &y,int &flag,char s[]){//分离x,y flag代表命题编号 int i,j; char t[100]; strcpy(t,s); for(i=0;i<strlen(s);i++){ if(t[i]==' '){ t[i]='\0'; break; } } x=atoi(t); if(strcmp(t+i+1,"is the root")==0){//命题1 flag=1; return; } if(s[strlen(s)-1]=='s'){//命题2 for(int j=strlen(s)-1;j>=0;j--){ if(t[j]==' '&&isdigit(t[j-1])){ t[j]='\0'; break; } } y=atoi(t+i+5); flag=2; return; } for(j=strlen(s)-1;j>=0;j--){ if(t[j]==' '){ break; } } y=atoi(t+j+1); flag=(t[i+4]=='t'?3:4);//命题3和命题4 return; } int main(){ int m,x,y,flag,is,locx,locy; char s[100]; cin>>n>>m; for(int i=1;i<=n;i++){ cin>>heap[i]; PrecUp(i); } getchar(); for(int i=1;i<=m;i++){ gets(s); Deal(x,y,flag,s); for(int j=1;j<=n;j++){ if(heap[j]==x){ locx=j; } else if(heap[j]==y){ locy=j; } } is=0; if(flag==1&&locx==1){ is=1; } else if(flag==2&&locx/2==locy/2){ is=1; } else if(flag==3&&locy/2==locx){ is=1; } else if(flag==4&&locx/2==locy){ is=1; } printf("%c\n",is==1?'T':'F'); } return 0; }