代码长度限制 16 KB
时间限制 400 ms
内存限制 64 MB
题目描述
将一系列给定数字顺序插入一个初始为空的小顶堆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
个人思路
- 用一个vector< int >来存入节点键值,然后用它来建立小顶堆
- 建立小顶堆踩到个坑,本来打算用makeheap一次性建立小顶堆,但是这样有两个测试点一直过不去。原因在于,用makeheap建立小顶堆是,叶节点会自动进行大小排序,而并不是简单按照二维数组的先后顺序进行逐个插入来建立的(这种手动建立小顶堆的方法在代码中注释掉的部分也有记录)。所以可以在动态输入插入时不断进行makeheap或者用pushleap()的方法。这样就能通过了。
- 将所有命题存入一个二维动态数组里,这里采用istringstream类型获取字符串,然后用while对其处理,通过空格分割字符串便可以将每个命题的每个单词分别存入。
- 最后各种命题的特征对每条命题进行判断
- 另外还有一个小坑,就是在判断数字下标时需要先对字符串做转整型的处理,因为节点键值的范围存在负数,所以要对第一个字符做符号判断。
- 当然也可以不用动态二维数组的方法,因为只需要对每条命令的第二个(用于判断第三个是获取字符串还是获取整形)和第四个单词进行判断便可区分不同的命令,然后对到达数字的位置直接获取整型数值就好了,这样便可以避免转数字可能碰到的一些坑。
#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
vector<ll> v;
ll getsum(string s)
{
ll rtn=0;
int flag=1;
if(s[0]=='-')
{
flag=-1;
}
else
{
flag=1;
rtn=s[0]-'0';
}
for(ll i=1;i<s.length();i++)
{
rtn=rtn*10+(s[i]-'0');
}
//cout<<rtn<<endl;
rtn*=flag;
for(ll i=0;i<v.size();i++)
{
if(rtn==v[i])
return i;
}
return -1;
}
int main()
{
ll n,m;
cin>>n>>m;
/*for (int i = 0; i < n;i++){//建立小顶堆
int a;
cin>>a;
v.push_back(a);
int k=i;
while(k>0&&v[k]<v[(k-1)/2]){
swap(v[k],v[(k-1)/2]);
k=(k-1)/2;
}
}*/
while(n--)
{
ll x;
cin>>x;
v.push_back(x);
push_heap(v.begin(),v.end(),greater<ll>());
}
//for(int i=0;i<v.size();i++)
//cout<<v[i]<<" ";
//cout<<endl;
vector<vector<string>> vv;
getchar();
while(m--)
{
string str;
getline(cin,str);
vector<string> vt;
istringstream s(str);
string out;
while(s>>out)
{
vt.push_back(out);
}
vv.push_back(vt);
vt.clear();
}
/*for(int i=0;i<vv.size();i++)
{
for(int j=0;j<vv[i].size();j++)
{
cout<<vv[i][j]<<" ";
}
cout<<endl;
}*/
for(ll i=0;i<vv.size();i++)
{
if(vv[i][1]=="and")
{
ll x=getsum(vv[i][0]);
ll y=getsum(vv[i][2]);
if(x==-1||y==-1)
{
cout<<"F"<<endl;
continue;
}
if(((x-1)/2)==((y-1)/2))
cout<<"T"<<endl;
else
cout<<"F"<<endl;
}
else if(vv[i][3]=="child")
{
ll x=getsum(vv[i][0]);
ll y=getsum(vv[i][5]);
if(x==-1||y==-1)
{
cout<<"F"<<endl;
continue;
}
if(y==((x-1)/2))
cout<<"T"<<endl;
else
cout<<"F"<<endl;
}
else if(vv[i][3]=="root") /**/
{
if(getsum(vv[i][0])==-1||getsum(vv[i][0])==-1)
{
cout<<"F"<<endl;
continue;
}
if(getsum(vv[i][0])==0)
cout<<"T"<<endl;
else
cout<<"F"<<endl;
}
else
{
ll x=getsum(vv[i][0]);
ll y=getsum(vv[i][5]);
if(x==-1||y==-1)
{
cout<<"F"<<endl;
continue;
}
if(x==(y-1)/2)
cout<<"T"<<endl;
else
cout<<"F"<<endl;
}
}
}