1. 程式人生 > >PAT L2-012. 關於堆的判斷(最小堆調整)

PAT L2-012. 關於堆的判斷(最小堆調整)

將一系列給定數字順序插入一個初始為空的小頂堆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
題意and解題思路:讓你建立一個最小堆,根據這個最小堆的實際情況去判斷下列命題是否正確(有個坑點,這個最小堆不是等所有資料輸入完才開始調整的,而是沒進一個元素,就進行調整的),至於最小堆調整,便是將保證父節點比子節點大,若不是其中最小的,則取左右結點中較小的一個進行交換,一直到沒有交換出現,便中斷此操作。
#include<cstdio>
#include<cstring>
#include<vector>
#include<iostream>
#include<queue>
#include<map>
using namespace std;
const int maxn = 3005;
int m;
int val[maxn];
int vis[maxn];
map<int,int>ma;
int f;
void adjust(int x,int n)
{
    vis[x] = 1;
    int l = 2*x;
    int r = 2*x+1;
    if(r<=n)
    {
        if(val[r]<val[l])
        {
            if(val[r]<val[x])
            {
                swap(val[r],val[x]);
                f=1;
            }
        }
        else if(val[l]<val[r])
        {
            if(val[l]<val[x])
            {
                swap(val[l],val[x]);
                f=1;
            }
        }
    }
    else if(l<=n)
    {
        if(val[l]<val[x])
        {
            swap(val[l],val[x]);
            f=1;
        }
    }
}
int main()
{

    int n;
    cin >> n >> m;
    for(int i = 1 ; i <= n ; i ++)
    {
        cin >> val[i];
        while(1)
        {
            f = 0;
            memset(vis,0,sizeof(vis));
            for(int j = i ; j >= 2; j --)
            {
                int fa = j/2;
                if(!vis[fa])
                    adjust(fa,i);
            }
            if(!f)
                break;
        }

    }

//    for(int i = 1 ; i <= n ; i ++)
//        cout << val[i] <<endl;
    for(int i = 1; i <= n ; i ++)
        ma[val[i]] = i;
    for(int i = 0 ; i < m; i ++)
    {
        int a,b ;
        scanf("%d",&a);
        int id1,id2;
        id1 = ma[a];
        string s1;
        cin >> s1;
        if(s1[0]=='a')
        {
            scanf("%d",&b);
            getline(cin,s1);
            id2 = ma[b];
            if(id1==id2)
                puts("F");
            else if((id1/2)==(id2/2))
                puts("T");
            else
                puts("F");
        }
        else
        {
            cin >> s1;
            if(s1[0]=='a')
            {
                cin >> s1;
                cin >> s1;
                scanf("%d",&b);
                id2 = ma[b];
                if(id1==id2)
                    puts("F");
                else if(id1/2==id2)
                    puts("T");
                else
                    puts("F");
            }
            else
            {
                cin >> s1;
                if(s1[0]=='r')
                {

                    if(id1==1)
                        puts("T");
                    else
                        puts("F");
                }
                else
                {
                    cin >> s1;
                    scanf("%d",&b);
                    id2 = ma[b];
//                    cout << a<<' '<<id1<<' '<<b <<' '<<id2<<' ';
                    if(id1==id2)
                        puts("F");
                    else  if(id1==(id2/2))
                        puts("T");
                    else
                        puts("F");
                }
            }
        }
    }
//     for(int i = 1 ; i <= n ; i ++)
//        cout << val[i] <<endl;
    return 0 ;
}