L2-012 关于堆的判断 (25 分)

本文介绍了一个程序,该程序实现了一种方法来构建小顶堆,并针对给定的元素集合进行插入操作。随后,程序能够判断特定的关系是否存在于堆中的元素间,如根节点判断、兄弟节点判断等。

L2-012 关于堆的判断 (25 分)

将一系列给定数字顺序插入一个初始为空的小顶堆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(≤ 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

 

就是手写一个二叉排序树,so easy!!

# include <iostream>
# include <cmath>
# include <cstring>
# include <string>
# include <map>
# include <algorithm>
# include <vector>
# include <cstdio>
# include <string>
# include <queue>

using namespace std;
const int maxn = 10000;


void insert(int h[], int last)
{
    int father = last / 2;
    while( father && h[father] > h[last])
    {
        swap(h[father], h[last]);
        last = father;
        father = last / 2;
    }
}

bool find(int h[], int x, int a, int b, int len)
{
    int root = x;
    queue<int> q;
    q.push(root);
    while(!q.empty())
    {
        root = q.front();
        q.pop();
        int ta = h[root * 2];
        int tb = h[root * 2 + 1];
        if(ta == a && tb == b || ta == b && tb == a)
        {
            return true;
        }
        if(root * 2 <= len && root * 2 + 1 <= len)
        {
            q.push(root * 2);
            q.push(root * 2 + 1);
        }
    }
    return false;
}

bool find_p(int h[], int x, int a, int b, int len)
{
    int root = x;
    while(h[root] != a && root <= len)
    {
        root++;
    }
    if(h[root*2] == b || h[root * 2 + 1] == b)
    {
        return true;
    }
    return false;
}


bool judge(int h[], int len, int a, int b, string str)
{
    if(str == "root")
    {
        if(a == h[1])
        {
            return true;
        }
        else
            return false;
    }
    else if(str == "siblings")
    {
        return find(h, 1, a, b, len);
    }
    else if(str == "parent")
    {
        return find_p(h, 1, a, b, len);
    }
    else
    {
         return find_p(h, 1, b, a, len);
    }
}



int main(int argc, char *argv[])
{
    int h[maxn];
    int n, m;
    cin >> n >> m;
    for(int i = 1; i <= n; i++)
    {
        cin >> h[i];
        insert(h, i);
    }

    for(int i = 0; i < m; i++)
    {
        int a , b;
        string str, link;
        cin >> a >> str;
        if(str != "and")
        {
            cin >> str >> link;//root
            if(link != "root")
            {
                cin >> str >> b;//parent child
            }
        }
        else
        {
            cin >> b >> str >> link;//siblings
        }
        bool flag = judge(h, n, a, b, link);
        if(flag)
        {
            cout <<"T" << endl;
        }
        else
        {
            cout << "F" << endl;
        }
    }

    return 0;
}

 

#include <REGX52.H> // 按键定义 sbit SET   = P3^1;  // 设置键(模式切换) sbit Add   = P3^0;  // 加键 sbit Sub   = P3^2;  // 减键 sbit START = P3^3;  // 启动/暂停键 // 输出控制 sbit BUZZER = P2^5;   // 蜂鸣器控制(无源) sbit RELAY  = P2^7;   // 继电器控制 sbit LED    = P2^6;   // 状态指示灯 // 时间变量 unsigned char shi = 0xFF, fen = 0xFF, miao = 0xFF;  // 初始值设为0xFF表示未设置 // 控制变量 unsigned char mode = 0;         // 0:正常计时 1:设置小时 2:设置钟 3:设置秒钟 bit run = 0;          // 计时运行状态 (1:运行, 0:暂停) bit finished = 0;               // 倒计时结束标志 bit initial_display = 1;        // 初始显示标志 // 定时器变量 unsigned int timer_count = 0;   // 定时器计数 unsigned char flash = 0        // 闪烁控制计数器 // 蜂鸣器控制变量 bit beep_enable = 0;            // 蜂鸣器使能标志 bit beep_requested = 0;         // 蜂鸣器请求标志 unsigned int beep_counter = 0;  // 蜂鸣器计数器 unsigned int beep_freq = 1000;  // 蜂鸣器频率 (默认1kHz) // 共阴数码管段码表 (0-9和横杠) unsigned char code duanxuan[] = {     0x3f,  // 0     0x06,  // 1     0x5b,  // 2     0x4f,  // 3     0x66,  // 4     0x6d,  // 5     0x7d,  // 6     0x07,  // 7     0x7f,  // 8     0x6f,  // 9     0x40   // 横杠 }; // 74LS138译码器位选控制 void SelectDigit(unsigned char digit) {     // 使用P2.2-P2.4控制74LS138的A0-A2     // 反转位选顺序:0->7, 1->6, 2->5, 3->4, 4->3, 5->2, 6->1, 7->0     digit = 7 - digit;     P2 = (P2 & 0xE3) | ((digit & 0x07) << 2); } // 函数声明 void Display(); void shezhi(); void Delay(unsigned int x); void T0_init(); void BeepOn(unsigned int freq); void BeepOff(); void PowerOnBeep(); // 延时函数 void Delay(unsigned int x) {     unsigned int i, j;     for(i = 0; i < x; i++)         for(j = 0; j < 110; j++); } // 开启蜂鸣器 void BeepOn(unsigned int freq) {     beep_enable = 1;     beep_freq = freq;     beep_counter = 0; } // 关闭蜂鸣器 void BeepOff() {     beep_enable = 0;     BUZZER = 0; // 确保蜂鸣器关闭 } // 上电提示音 void PowerOnBeep() {     unsigned char i;     for(i = 0; i < 100; i++) {         BUZZER = ~BUZZER;         Delay(1);     }     BUZZER = 0; } void T0_init() {     TMOD = 0x01;          // 定时器0工作方式1     TH0 = (65536 - 1000) / 256;  // 1ms定时     TL0 = (65536 - 1000) % 256;          EA = 1;   // 开启总中断(全局中断使能位)     ET0 = 1;  // 开启定时器0中断(定时器0中断使能位)     TR0 = 1;  // 启动定时器0(定时器0运行控制位01) } void T0_isr() interrupt 1 {     TH0 = (65536 - 1000) / 256;  // 重新装载初值     TL0 = (65536 - 1000) % 256;          timer_count++;   // 定时器计数加1          // 蜂鸣器控制 - 产生方波     if(beep_enable) {         beep_counter++;         // 根据频率翻转蜂鸣器状态 (每半周期翻转一次)         if(beep_counter >= (1000 / (2 * beep_freq))) {             beep_counter = 0;             BUZZER = ~BUZZER;         }     }          // 每50ms更新一次显示和状态     if(timer_count % 400 == 0) {         flash = ~flash; // 翻转闪烁状态     }          // 每秒更新一次时间     if(timer_count >= 1000) {         timer_count = 0;                  // 仅在正常计时模式且运行时进行时间递减         if(mode == 0 && run && !finished) {             // 倒计时逻辑             if(miao > 0) {                 miao--;             } else {                 if(fen > 0) {                     fen--;                     miao = 59;                 } else {                     if(shi > 0) {                         shi--;                         fen = 59;                         miao = 59;                     } else {                         // 倒计时结束                         shi = 0;                         fen = 0;                         miao = 0;                         run = 0;    // 停止计时                         finished = 1; // 设置结束标志                         beep_requested = 1; // 请求启动蜂鸣器                     }                 }             }         }     } } // 数码管显示函数 void Display() {     // 上电初始显示"----"     if(initial_display) {         // 显示小时十位 (横杠)         SelectDigit(0);         P0 = duanxuan[10]; // 横杠         Delay(1);         P0 = 0x00;                  // 显示小时个位 (横杠)         SelectDigit(1);         P0 = duanxuan[10]; // 横杠         Delay(1);         P0 = 0x00;                  // 显示隔符(横杠)         SelectDigit(2);         P0 = duanxuan[10]; // 横杠         Delay(1);         P0 = 0x00;                  // 显示钟十位 (横杠)         SelectDigit(3);         P0 = duanxuan[10]; // 横杠         Delay(1);         P0 = 0x00;                  // 显示钟个位 (横杠)         SelectDigit(4);         P0 = duanxuan[10]; // 横杠         Delay(1);         P0 = 0x00;                  // 显示隔符(横杠)         SelectDigit(5);         P0 = duanxuan[10]; // 横杠         Delay(1);         P0 = 0x00;                  // 显示秒钟十位 (横杠)         SelectDigit(6);         P0 = duanxuan[10]; // 横杠         Delay(1);         P0 = 0x00;                  // 显示秒钟个位 (横杠)         SelectDigit(7);         P0 = duanxuan[10]; // 横杠         Delay(1);         P0 = 0x00;                  return;     }          // 正常显示模式     // 显示小时十位     SelectDigit(0);     if(shi == 0xFF) {         P0 = duanxuan[10]; // 显示横杠(未设置)     } else if(mode == 1 && (flash & 0x01) == 0) { // 设置小时时闪烁         P0 = 0x00;     } else {         P0 = duanxuan[shi/10];     }     Delay(1);     P0 = 0x00;          // 显示小时个位     SelectDigit(1);     if(shi == 0xFF) {         P0 = duanxuan[10]; // 显示横杠(未设置)     } else if(mode == 1 && (flash & 0x01) == 0) {          P0 = 0x00;     } else {         P0 = duanxuan[shi%10];     }     Delay(1);     P0 = 0x00;          // 显示隔符(横杠)     SelectDigit(2);     P0 = duanxuan[10];      Delay(1);     P0 = 0x00;          // 显示钟十位     SelectDigit(3);     if(fen == 0xFF) {         P0 = duanxuan[10]; // 显示横杠(未设置)     } else if(mode == 2 && (flash & 0x01) == 0) {          P0 = 0x00;     } else {         P0 = duanxuan[fen/10];     }     Delay(1);     P0 = 0x00;          // 显示钟个位     SelectDigit(4);     if(fen == 0xFF) {         P0 = duanxuan[10]; // 显示横杠(未设置)     } else if(mode == 2 && (flash & 0x01) == 0) {          P0 = 0x00;     } else {         P0 = duanxuan[fen%10];     }     Delay(1);     P0 = 0x00;          // 显示隔符(横杠)     SelectDigit(5);     P0 = duanxuan[10];      Delay(1);     P0 = 0x00;          // 显示秒钟十位     SelectDigit(6);     if(miao == 0xFF) {         P0 = duanxuan[10]; // 显示横杠(未设置)     } else if(mode == 3 && (flash & 0x01) == 0) {          P0 = 0x00;     } else {         P0 = duanxuan[miao/10];     }     Delay(1);     P0 = 0x00;          // 显示秒钟个位     SelectDigit(7);     if(miao == 0xFF) {         P0 = duanxuan[10]; // 显示横杠(未设置)     } else if(mode == 3 && (flash & 0x01) == 0) {          P0 = 0x00;     } else {         P0 = duanxuan[miao%10];     }     Delay(1);     P0 = 0x00; } // 按键处理函数 void shezhi() {     // 设置键处理     if(SET == 0) {         Delay(5);         if(SET == 0) {             while(!SET); // 松手检测                          mode++;             if(mode > 3) mode = 0;                          // 设置模式时取消初始显示             initial_display = 0;                          // 初始化未设置的时间值             if(mode == 1 && shi == 0xFF) shi = 0;             if(mode == 2 && fen == 0xFF) fen = 0;             if(mode == 3 && miao == 0xFF) miao = 0;         }     }          // 加键处理     if(Add == 0) {         Delay(5);         if(Add == 0) {             while(!Add); // 松手检测             initial_display = 0; // 取消初始显示                          if(mode == 1) { // 设置小时                 shi++;                 if(shi > 12) shi = 0;             }             else if(mode == 2) { // 设置钟                 fen++;                 if(fen > 59) fen = 0;             }             else if(mode == 3) { // 设置秒钟                 miao++;                 if(miao > 59) miao = 0;             }         }     }          // 减键处理     if(Sub == 0) {         Delay(5);         if(Sub == 0) {             while(!Sub); // 松手检测             initial_display = 0; // 取消初始显示                          if(mode == 1) { // 设置小时                 if(shi == 0) shi = 12;                 else shi--;             }             else if(mode == 2) { // 设置钟                 if(fen == 0) fen = 59;                 else fen--;             }             else if(mode == 3) { // 设置秒钟                 if(miao == 0) miao = 59;                 else miao--;             }         }     }          // 启动/暂停键处理     if(START == 0) {         Delay(5);         if(START == 0) {             while(!START); // 松手检测             initial_display = 0; // 取消初始显示                          if (finished) {                 // 倒计时结束后的处理:停止蜂鸣器和继电器,清除结束标志                 finished = 0;                 beep_requested = 0; // 清除蜂鸣器请求                 BeepOff();  // 关闭蜂鸣器                 RELAY = 1;  // 断开继电器                 LED = 0;    // 关闭状态指示灯             } else if(mode == 0) { // 只有在正常显示模式下才能启动/暂停                 // 检查时间是否已设置                 if(shi != 0xFF && fen != 0xFF && miao != 0xFF) {                     run = ~run; // 状态取反                     LED = run;  // 更新指示灯状态                 }             }         }     } } void main() {     P0 = 0x00;  // 初始化P0口     P2 = 0x00;  // 初始化P2口     BUZZER = 0; // 初始关闭蜂鸣器(无源蜂鸣器需要低电平关闭)     RELAY = 1;  // 初始断开继电器     LED = 0;    // 初始关闭状态指示灯          // 上电提示音     PowerOnBeep();          T0_init();  // 定时器初始化          while(1) {         shezhi();   // 按键处理         Display();  // 显示                  // 倒计时结束处理         if(finished) {             RELAY = 0;  // 继电器通电吸合                          // 状态指示灯闪烁             LED = flash & 0x01;                          // 启动蜂鸣器(主循环直接控制)             if(beep_requested) {                 beep_requested = 0;                 BeepOn(1000);  // 启动1kHz蜂鸣             }         } else {             // 非结束状态下,指示灯显示运行状态             LED = run;                          // 确保在非结束状态关闭蜂鸣器             if(beep_enable) {                 BeepOff();             }         }     } }以此程序给我画出软件程序设计的主程序流程图,子程序流程图以及中断服务程序
最新发布
06-30
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值