*浙大PAT甲级 1110 判断是否为完全二叉树

本文介绍了一种使用广度优先搜索(BFS)判断一棵树是否为完全二叉树的方法。核心思想在于检查节点是否有不匹配的孩子节点状态,即左空右非空或前一节点无子节点而当前节点有子节点的情况。

这个题关键是如何判断是否为完全二叉树。

通过bfs广搜来进行判断如果一个结点没有左二子,有右儿子那么不是完全二叉树;或者前一个结点无左二子或者俩个儿子都没有而这个结点却有孩子,那么不是完全二叉树。否则就是完全二叉树。

AC代码:

#include<iostream>
#include<map>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
#include<set>
#include<stack>
#include<cmath>
#include<vector>
#include<hash_map>
#define ll long long
#define inf 24*60*60
using namespace std;
struct node
{
    int id;
    int l=-1;
    int r=-1;
};
node a[20];
int mark[20];
int yy=10;
bool bfs(int x)
{
    queue<node> q;
    q.push(a[x]);
    int flag=0;
    while(!q.empty())
    {
        node tmp=q.front();
        q.pop();
        int flag1=0;
        int flag2=0;
        if(tmp.l!=-1)
        {
            if(flag==1)
            {
                return false;
            }
            q.push(a[tmp.l]);
            flag1=1;
        }
        if(tmp.r!=-1)
        {
            if(flag==1)
            {
                return false;
            }
            q.push(a[tmp.r]);
            flag2=1;
        }
        if(flag1==0&&flag2==1)
        {
            return false;
        }
        if(flag1==1&&flag2==0)
        {
            flag=1;
        }
        if(flag1==0&&flag2==0)
        {
            flag=1;
        }
        if(q.empty())
        {
            yy=tmp.id;
        }
    }
    return true;
}
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        char l[4];
        char r[4];
        scanf("%s %s",l,r);
        if(l[0]!='-')
        {
            int sum=0;
            for(int j=0;j<strlen(l);j++)
            {
                sum*=10;
                sum+=l[j]-'0';
            }
            a[i].l=sum;
            mark[sum]=1;
        }
        if(r[0]!='-')
        {
            int sum=0;
            for(int j=0;j<strlen(r);j++)
            {
                sum*=10;
                sum+=r[j]-'0';
            }
            a[i].r=sum;
            mark[sum]=1;
        }
        a[i].id=i;
    }
    int biao;
    for(int i=0;i<n;i++)
    {
        if(mark[i]==0)
        {
            biao=i;
            break;
        }
    }
    bool gg=bfs(biao);
    if(gg==true)
    {
        printf("YES %d",yy);
    }
    else
    {
        printf("NO %d",biao);
    }
}


<think>嗯,用户问的是零基础参加PAT甲级考试需要准备多久,怎么准备。首先,我得了解PAT甲级考试的内容和要求。PAT是浙江大学计算机程序设计能力考试,甲级主要考察数据结构和算法,编程能力。用户零基础的话,可能需要从编程语言学起,比如C++或者Java,然后学习数据结构和算法。 接下来,用户可能需要一个详细的学习计划。通常来说,零基础到能通过甲级考试需要的时间因人而异,但一般可能需要4到6个月。需要分阶段来规划,比如先学编程语言基础,再数据结构,然后算法,最后刷题。 然后,具体每个阶段的时间分配。比如第一个月学C++基础,包括语法、循环、函数、指针这些。然后第二个月学数据结构,比如链表、树、图等。第三个月学算法,排序、搜索、动态规划等等。之后两个月刷题,尤其是PAT的真题,还有LeetCode上的题目。最后一个月模拟考试,调整节奏。 还要考虑资源推荐,比如推荐的书籍,像《算法笔记》,或者在线课程,比如MOOC上的浙大数据结构课程。另外,刷题平台除了PAT真题,可能还需要LeetCode、牛客网等。 用户可能没有考虑到的是考试环境,比如PAT使用的是C/C++或Java,所以得熟悉编程环境,还有时间管理,每个题目大概20分钟,总共4题,所以平时练习要注意速度。此外,调试能力和边界条件处理也很重要,考试中常见的问题比如超时、内存超限,这些都需要在练习中注意。 另外,用户可能需要知道考试报名时间和次数,PAT一年有四次,所以如果一次没准备好,可以下次再考。不过用户可能希望一次成功,所以时间安排要合理,每天保持一定的学习时间,比如每天3-4小时,持续几个月。 还要提醒用户注意错题总结,建立自己的错题本,分析错误原因,避免重复犯错。同时,参加在线社区或者找学习小组,互相讨论问题,可能会提高效率。 最后,模拟考试的重要性,提前适应考试节奏,限时完成题目,培养心理素质,避免考试时紧张。总之,系统学习加大量练习是关键,合理安排时间,坚持下来应该没问题。</think>以下为零基础备战PAT甲级考试的系统性指南,分为三个阶段规划(建议总时长4-6个月): --- ### **一、基础筑基阶段(1.5-2个月)** **目标**:掌握C++语言基础与数据结构核心知识 1. **C++语法基础**(15天) - 每日投入3小时 - 必学内容: ```cpp // 示例:快速排序模板(需理解语法结构) void quickSort(int q[], int l, int r) { if (l >= r) return; int i = l-1, j = r+1, x = q[(l+r)>>1]; while(i < j) { do i++; while(q[i] < x); do j--; while(q[j] > x); if(i < j) swap(q[i], q[j]); } quickSort(q, l, j), quickSort(q, j+1, r); } ``` - 重点:数组操作、STL容器(vector/map/set/stack/queue)、指针与引用 2. **数据结构入门**(1个月) - 必学内容树状图: ``` 线性结构 → 链表 → 树 → 二叉树 → 二叉搜索树 → 堆 → 图 ``` - 配套教材:《算法笔记》第3-5章(胡凡著) --- ### **二、算法强化阶段(2-3个月)** **目标**:掌握20+高频算法模型与优化策略 1. **核心算法专项突破** | 算法类型 | 典型例题 | 训练量 | |----------------|---------------------------|--------| | 深度优先搜索 | 全排列、N皇后问题 | 20题 | | 动态规划 | 背包问题、最长公共子序列 | 25题 | | 图论算法 | Dijkstra、拓扑排序 | 15题 | 2. **解题技巧提升** - 时间复杂度分析(如将$O(n^2)$优化到$O(n\log n)$) - 边界条件处理(特别注意数据范围:$1 \leq n \leq 10^5$类问题) - 调试技巧:使用assert语句验证中间结果 --- ### **三、实战冲刺阶段(1个月)** **目标**:建立稳定的110分钟解题节奏(满分100分,4题) 1. **真题训练策略** - 使用[PAT官网真题库](https://pintia.cn/problem-sets) - 模拟考试要求:闭卷、禁用IDE、仅允许纸质笔记 - 高频考点分布: $$ \text{字符串处理} \approx 25\%,\quad \text{树形结构} \approx 30\%,\quad \text{图论} \approx 35\% $$ 2. **考场应对锦囊** - 时间分配建议:简单题20分钟,中等题30分钟,难题60分钟 - 备用模板:预先准备并手写如下模板 ```cpp // 并查集模板(考场可直接默写) int parent[MAXN]; int find(int x) { return parent[x] == x ? x : parent[x] = find(parent[x]); } void unite(int x, int y) { parent[find(x)] = find(y); } ``` --- ### **四、辅助工具推荐** 1. 在线评测平台: - [Codeup](https://codeup.host)(含PAT真题分类) - [LeetCode](https://leetcode.com)(重点练习「Hard」标签题) 2. 调试工具: - C++调试宏(考前熟记): ```cpp #define debug(x) cerr << #x << " = " << x << endl ``` --- ### **五、常见问题预警** 1. **内存溢出**:避免使用$O(n^2)$空间复杂度算法处理$n=10^5$数据 2. **超时陷阱**:优先选择非递归写法替代递归(如DFS改用栈实现) 3. **浮点误差**:比较浮点数时使用: ```cpp const double eps = 1e-8; bool equal(double a, double b) { return fabs(a-b) < eps; } ``` 建议保持每日3-4小时有效训练量,重点突破树形结构和动态规划模块。若真题模拟稳定在80分以上,可尝试正式报考。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值