C4top-關於堆的判斷 (最小堆)

kewlgrl發表於2017-03-19
關於堆的判斷   

將一系列給定數字順序插入一個初始為空的小頂堆H[]。隨後判斷一系列相關命題是否為真。命題分下列幾種:

  • x is the rootx是根結點;
  • x and y are siblingsxy是兄弟結點;
  • x is the parent of yxy的父結點;
  • x is a child of yxy的一個子結點。

輸入格式:

每組測試第1行包含2個正整數N\le 1000)和M\le 20),分別是插入元素的個數、以及需要判斷的命題數。下一行給出區間[-10000, 10000][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
 
  • 時間限制:400ms
  • 記憶體限制:64MB
  • 程式碼長度限制:16kB
  • 判題程式:系統預設
  • 作者:陳越
  • 單位:浙江大學

題目判定

解題思路
用陣列模擬一個最小堆,輸入一個數就更新一次,不能輸入完畢後一次性建堆。
根據每句話的特點分辨出要求的是什麼,並分離出數值量。
父節點下標如果是i,則子節點下標是i*2+1和i*2。
注意可能存在負數,如果用的一次讀入一行含空格的字元穿,還需要吃掉第一行的回車符。
判斷輸入的程式碼巨醜……見諒(っ*´Д`)っ

解題程式
#include<cstdio>
#include<cstring>
#include<cmath>
#include<set>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
#define MAXN 200010
#define INF 0x3f3f3f3f
int heap[MAXN],sz=0;
int cmp(int a,int b)
{
    return a>b;
}
void push(int x)
{
    int i=++sz;
    while(i>1)
    {
        int p=i/2;//父親節點的編號
        if(heap[p]<=x) break;//已經沒有大小顛倒
        heap[i]=heap[p];//交換節點數值
        i=p;
    }
    heap[i]=x;
}

int pop()
{
    int ret=heap[0];
    int temp=sz;
    int x=heap[--temp];
    int i=0;
    while(i*2+1<temp)
    {
        int a=i*2+1,b=i*2+2;
        if(b<temp&&heap[b]<heap[a]) a=b;
        if(heap[a]>=x) break;
        heap[i]=heap[a];
        i=a;
    }
    heap[i]=x;
    return ret;
}
int main()
{
#ifdef ONLINE_JUDGE
#else
    freopen("G:/cbx/read.txt","r",stdin);
    //freopen("G:/cbx/out.txt","w",stdout);
#endif
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n,m;
    cin>>n>>m;
    for(int i=0; i<n; ++i)
    {
        int x;
        cin>>x;
        push(x);
    }
    int flag=-1;
    char s[100];
    cin.getline(s,100);// 吃掉回車符
    for(int i=0; i<m; ++i)
    {
        int a=0,b=0,pos,minu=1;
        cin.getline(s,100);
        //cout<<s<<endl;
        int len=strlen(s);
        if(s[len-1]=='t')//是根結點
        {
            flag=1;
            for(int j=0; j<len; ++j)
            {
                if(s[j]=='-')
                {
                    minu=-1;
                    continue;
                }
                a*=10;
                a+=int(s[j]-'0');
                if(s[j+1]==' ')
                {
                    a*=minu;
                    break;
                }
            }
        }
        else if(s[len-1]=='s')//是兄弟結點
        {
            flag=2;
            for(int j=0; j<len; ++j)
            {
                if(s[j]=='-')
                {
                    minu=-1;
                    continue;
                }
                a*=10;
                a+=int(s[j]-'0');
                if(s[j+1]==' ')
                {
                    a*=minu;
                    minu=1;
                    pos=j+6;
                    break;
                }
            }
            for(int j=pos; j<len; ++j)
            {
                if(s[j]=='-')
                {
                    minu=-1;
                    continue;
                }
                b*=10;
                b+=int(s[j]-'0');
                if(s[j+1]==' ')
                {
                    b*=minu;
                    break;
                }
            }
        }
        else
        {
            int cnt=0;
            for(int j=0; j<len; ++j)
            {
                if(s[j]==' ') ++cnt;
                if(cnt==2)
                {
                    if(s[j+1]=='t')
                    {
                        flag=3;//是父結點
                        for(int k=0; k<len; ++k)
                        {
                            if(s[k]=='-')
                            {
                                minu=-1;
                                continue;
                            }
                            a*=10;
                            a+=int(s[k]-'0');
                            if(s[k+1]==' ')
                            {
                                a*=minu;
                                minu=1;
                                pos=k+19;
                                break;
                            }
                        }
                        for(int k=pos; k<len; ++k)
                        {
                            if(s[k]=='-')
                            {
                                minu=-1;
                                continue;
                            }
                            b*=10;
                            b+=int(s[k]-'0');
                            if(s[k+1]=='\0')
                            {
                                b*=minu;
                                break;
                            }
                        }
                    }
                    else if(s[j+1]=='a')
                    {
                        flag=4;//是子結點
                        for(int k=0; k<len; ++k)
                        {
                            if(s[k]=='-')
                            {
                                minu=-1;
                                continue;
                            }
                            a*=10;
                            a+=int(s[k]-'0');
                            if(s[k+1]==' ')
                            {
                                a*=minu;
                                minu=1;
                                pos=k+16;
                                break;
                            }
                        }
                        for(int k=pos; k<len; ++k)
                        {
                            if(s[k]=='-')
                            {
                                minu=-1;
                                continue;
                            }
                            b*=10;
                            b+=int(s[k]-'0');
                            if(s[k+1]=='\0')
                            {
                                b*=minu;
                                break;
                            }
                        }
                    }
                    if(flag!=-1) break;
                }
            }
        }
        //cout<<a<<" "<<b<<endl;
        if(flag==1)//是根結點
        {
            if(heap[1]==a) cout<<"T"<<endl;
            else cout<<"F"<<endl;
        }
        else if(flag==2)//是兄弟結點
        {
            int j=0;
            for(int i=1; i<=n; ++i)
                if(heap[i]==a)
                {
                    j=i;
                    break;
                }
            j/=2;
            if(j!=0&&((heap[j*2]==a&&heap[j*2+1]==b)||(heap[j*2]==b&&heap[j*2+1]==a)))
                cout<<"T"<<endl;
            else cout<<"F"<<endl;
        }
        else if(flag==3)//是父結點
        {
            int j=0;
            for(int i=1; i<=n; ++i)
                if(heap[i]==a)
                {
                    j=i;
                    break;
                }
            if(j!=0&&((heap[j*2]==b||heap[j*2+1]==b)))
                cout<<"T"<<endl;
            else cout<<"F"<<endl;
        }
        else if(flag==4)//是子結點
        {
            int j=0;
            for(int i=1; i<=n; ++i)
                if(heap[i]==a)
                {
                    j=i;
                    break;
                }
            if(j!=0&&((heap[j/2]==b||heap[(j-1)/2]==b)))
                cout<<"T"<<endl;
            else cout<<"F"<<endl;
        }
    }
}


相關文章