思路:
就是建立一个堆,然后找是否满足4个条件就好了。
观察可知,这四个条件都是对坐标关系的判断,接下来我用pos(x)表示x在堆中的位置。
(1)x是根节点 :如果pos(x)== 1;
(2)x和y是兄弟节点 :pos(x)/2 == pos(y)/2;
(3)x是y的父节点:pos(x)== pos(y)/2;
(4)x是y的儿子节点:pos(x)/2 == pos (y);
注意:只满足以上条件还不行,
还要注意输入的格式,由于数字是区间[−10000,10000]内的,所以直接用字符串getline输入
的话还要判断负数,比较麻烦,
由于每一句话的单词数量基本一致,所以可以采用输入不同字符串的方式来记录数据。
(一开始错误就是没考虑负数)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
#include<string>
using namespace std;
const int maxn = 100100;
int h[maxn]={0},len=0,t1,t2;
map <int,int> mp;
void Ins(int x)
{
int i;
for(i=++len;i>0;i/=2)
if(h[i/2]>x) h[i]=h[i/2];
else break;
h[i]=x;
}
int main(void)
{
int n,m,i,j,x,y;
h[0]=-100010;
scanf("%d%d",&n,&m);
for(i=0;i<n;i++){
scanf("%d",&x);Ins(x);
}
for(i=1;i<=len;i++) mp[h[i]]=i;
char ss[120],ch,s1[120],s2[120];
getchar();
while(m--){
scanf("%d %s",&x,ss);
if(strcmp(ss,"is")==0){
scanf("%s %s",s1,s2);
if(strcmp(s1,"a")==0){ //x ch y
scanf("%s %d",ss,&y);
if(mp[x]/2==mp[y]) puts("T");
else puts("F");
}else{
if(strcmp(s2,"root")==0){ //toot
if(mp[x]==1) puts("T");
else puts("F");
}else{ //x par y
scanf("%s %d",s1,&y);
if(mp[x]==mp[y]/2) puts("T");
else puts("F");
}
}
}else{ //sub
scanf("%d %s %s",&y,s1,s2);
if(mp[x]/2==mp[y]/2) puts("T");
else puts("F");
}
}
return 0;
}