PAT甲级2023夏季考试题解(A-1 Trap,A-2 Queue Using Two Stacks,A-3 Rank of Binary Tree,A-4 Big Number)

2023-11-04

很幸运得到了一个满分,最后一题真的是连蒙带猜的AC的,当AC的那瞬间,可以用喜极而泣来形容了,去年十二月也参加了一次甲级,但是才考到89分,不是很满意,因此这次又去参加了一次。但总算得到了一点收获,也算对自己的一点安慰吧。

A-1 Trap

分数 20

作者 陈越

单位 浙江大学

A robot is designed to move on a map from South toward North. When some obstacle is encountered, the robot can only turn toward West and moves until it can turn toward North and continue.

Given a squared map with n×n blocks, a robot can start from any position below the bottom line (South) and its target is to reach the top line (North). (By the way, kindly remind you that the left-hand-side of the map is West and the right-hand-side is East.)

If some obstacles are placed in the map, the robot might get trapped if it starts from certain positions and can never reach the North line. For example, in the situation given by the following figure, the robot will be trapped if it starts from either position 7 or 8.

Your job is to point out those starting positions which will get the robot trapped.

Note: it is assumed that a robot can move out of the map boundary, and all the blocks around the map are open, without any obstacle. Hence if the robot starts from any position out of the West or East boundary, it can certainly reach North without any problem. Therefore we only have to consider the positions between the West and East boundaries (e.g. the positions from 1 to 10 below the South line in the above figure). Besides, as long as the robot can reach the North line, it is considered successful even of it ends up at out of the boundary (e.g. the robot will have to move out of the map if starts from either the positions 1 or 2, but it can still reach the North line).

Input Specification:

Each input file contains one test case. Each case starts from a positive integer n (≤100) in a line, which is the size of the map. Then n lines follow, each contains n characters, which are either 0 for an open block, or 1 for a block with obstacle. The first line corresponds to the North boundary and the last line the South.

Output Specification:

Output in a line all the starting positions which can get the robot trapped, in increasing order. The positions are indexed from West to East, starting from 1. It is guaranteed that there is at least one output.
All the numbers must be separated by 1 space, and there must be no extra space at the beginning or the end of the line.

Sample Input:

10
0000000000
0000111010
1100100011
0000110001
0000000011
0000000000
0100000100
0001000000
0001000000
0001100000

Sample Output:

7 8

分析: 起点从第 n+1开始走,不是从第n行走;每次只有上方有阻碍物时,才可以往左走,
 * 如果左方也有阻碍物那么就走到了死胡同,不能走到最上方;但是到达左边界线
 * 或者上边界线,机器人一定能到达最上面;
 *
 * 根据上面的分析,可以写一个函数来判断从第i列开始走,能否到达上边界线

/**
 * 起点从第 n+1开始走,不是从第n行走;每次只有上方有阻碍物时,才可以往左走,
 * 如果左方也有阻碍物那么就走到了死胡同,不能走到最上方;但是到达左边界线
 * 或者上边界线,机器人一定能到达最上面;
 * 
 * 根据上面的分析,可以写一个函数来判断从第i列开始走,能否到达上边界线
*/

#include <iostream>
#include <set>

using namespace std;

const int N = 110;
char g[N][N];
int n;

bool trap(int y)
{
    bool block = false;
    int x = n+1;

    while(1)
    {
        //到达左边界线或者上边界线,机器人一定能到达最上面
        if(x == 1 || y == 1) 
            break;
        else if(x > 1 && g[x-1][y] == '0') //往北走
            --x;
        else if(y > 1 && g[x][y-1] == '0') //往西走
            --y;
        else
        {
            //上边不能走,左边也不能走,那么肯定遇到了死胡同,
            //不能到达最上边
            block = true; 
            break;
        }
    }

    return block;
}

int main()
{
    fill(*g, *g+N*N, '0');

    cin >> n;
    getchar();

    for(int i=1; i<=n; ++i)
    {
        for(int j=1; j<=n; ++j)
            scanf("%c", &g[i][j]);
        getchar();
    }

    set<int> st;

    for(int i=1; i<=n; ++i)
        if(trap(i) == true)
            st.insert(i);

    bool spa = false;
    for(auto ele : st)
    {
        if(spa) cout << ' ';
        else spa = true;
        cout << ele;
    }

    return 0;
}

A-2 Queue Using Two Stacks

分数 25

作者 陈越

单位 浙江大学

A queue (FIFO structure) can be implemented by two stacks (LIFO structure) in the following way:

  1. Start from two empty stacks s1​ and s2​.
  2. When element e is enqueued, it is actually pushed onto s1​.
  3. When we are supposed to dequeue, s2​ is checked first. If s2​ is empty, everything in s1​ will be transferred to s2​ by popping from s1​ and immediately pushing onto s2​. Then we just pop from s2​ -- the top element of s2​ must be the first one to enter s1​ thus is the first element that was enqueued.

Assume that each operation of push or pop takes 1 unit of time. You job is to tell the time taken for each dequeue.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (≤103), which are the number of operations. Then N lines follow, each gives an operation in the format

Operation Element

where Operation being I represents enqueue and O represents dequeue. For each I, Element is a positive integer that is no more than 106. No Element is given for O operations.
It is guaranteed that there is at least one O operation.

Output Specification:

For each dequeue operation, print in a line the dequeued element and the unites of time taken to do this dequeue. The numbers in a line must be separated by 1 space, and there must be no extra space at the beginning or the end of the line.
In case that the queue is empty when dequeue is called, output in a line ERROR instead.

Sample Input:

10
I 20
I 32
O
I 11
O
O
O
I 100
I 66
O

Sample Output:

20 5
32 1
11 3
ERROR
100 5

 

分析:根据题目描述,用两个初始为空的栈来实现队列的入队与出队操作,考试的时候,
 * 题目看了半天没看懂,最后模拟了一遍样例才弄懂了题意。
 *
 * 读懂题意后,这道题就是一个送分题,当然你得会STL,当然数组实现也不麻烦。

/**
 * 根据题目描述,用两个初始为空的栈来实现队列的入队与出队操作,考试的时候,
 * 题目看了半天没看懂,最后模拟了一遍样例才弄懂了题意。
 * 
 * 读懂题意后,这道题就是一个送分题,当然你得会STL,当然数组实现也不麻烦。
*/

#include <iostream>
#include <queue>
#include <stack>

using namespace std;

stack<int> stk1, stk2;

void POP()
{
    if(stk2.empty())
    {
        int sz2 = stk1.size();
        if(stk1.empty())
            puts("ERROR");
        else
        {
            while(stk1.size())
            {
                int u = stk1.top();
                stk1.pop();
                stk2.push(u);
            }
            int u = stk2.top();
            stk2.pop();
            cout << u << ' ' << 2 * sz2 + 1 << endl;
        }
    }
    else
    {
        int u = stk2.top();
        stk2.pop();
        cout << u << ' ' << 1 << endl;
    }
}

int main()
{
    int n;
    cin >> n;
    for(int i=0; i<n; ++i)
    {
        string op;
        int v;
        cin >> op;
        if(op == "I")
        {
            cin >> v;
            stk1.push(v);
        }
        else
            POP();

    }
    return 0;
}

A-3 Rank of Binary Tree

分数 25

作者 陈越

单位 浙江大学

Here we define the rank of a binary tree as n1​×n2​/n0​ where ni​ is the number of nodes of degree i for i=0,1,2.
For example, given a tree shown by the figure, its rank is 2×3/4=1.5.

Given the inorder and preorder traversal sequences of a binary tree, you are supposed to calculate its rank.

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive integer N (≤20), which is the total number of nodes in the tree. Then given in the following 2 lines are the inorder and preorder traversal sequences of the tree, respectively. All the keys in the tree are distinct positive integers in the range of int.

Output Specification:

For each case, print in a line the way we calculate the rank, and the integer part of the rank. The format is:

n1 * n2 / n0 = rank

Sample Input:

9
2 3 1 5 4 7 8 6 9
1 2 3 6 7 4 5 8 9

Sample Output:

2 * 3 / 4 = 1

分析:考察有前序与中序遍历构建一棵二叉树,最后再遍历一遍二叉树,求出度为0,1
 * ,2的结点个数,即能得到答案。

/**
 * 考察有前序与中序遍历构建一棵二叉树,最后再遍历一遍二叉树,求出度为0,1
 * ,2的结点个数,即能得到答案。
*/

#include <iostream>

using namespace std;

typedef struct TNode* Bin;
struct TNode
{
    int v;
    Bin l, r;
};

const int N = 50;
int pre[N], mid[N];
int n0, n1, n2;

Bin Create(int preL, int preR, int midL, int midR)
{
    if(preL > preR) return NULL;

    int root = pre[preL];
    int k;
    for(k=midL; mid[k] != root; ++k);

    int numL = k - midL;

    Bin t = new TNode;
    t->v = pre[preL];
    t->l = Create(preL+1, preL + numL, midL, k-1);
    t->r = Create(preL+numL+1, preR, k+1, midR);
    return t;
}

void pre_Traver(Bin T)
{
    if(T)
    {
        if(T->l && T->r)    n2++;
        else if(!T->l && !T->r) n0++;
        else n1++;
        pre_Traver(T->l);
        pre_Traver(T->r);
    }
}

int main()
{
    int n;
    cin >> n;
    for(int i=0; i<n; ++i)  cin >> mid[i];
    for(int i =0; i<n; ++i)  cin >> pre[i];

    Bin T = Create(0, n-1, 0, n-1);
    pre_Traver(T);

    int res = n1 * n2 / n0;

    printf("%d * %d / %d = %d", n1, n2, n0, res);

    return 0;
}

A-4 Big Number

分数 30

作者 陈越

单位 浙江大学

How to generate a big number of N digits randomly? One way is to find N kids, give each one a card with one's index written on one side (hence it is assumed that the kids are indexed from 1 to N), and ask them to write down a 1-digit number randomly on the other side. Then let the kids pin their digits in a line, on the wall, one by one in ascending order of their indices.

However, it's very difficult to let hundreds of thousands of kids to follow the order. The result is that we have cards pinned randomly all over the wall, some even show the wrong sides. For example, if the 23rd kid has written down 8, we are supposed to find the number 8 on the wall. But instead we might find 23... Your job is to rearrange these cards so that we can obtain the big number as required.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (≤105). Then N lines follow, each describes a card in the format n1 n2 where the two numbers are the numbers written on the two sides of a card.

Output Specification:

For each test case, print in a line the N-digit number as required. That is, print the digits written by the kids in ascending order of their indices. In case that there are 1-digit numbers written on both sides, it would be hard to tell which one is the index and which one is the number written by the kid. Hence the solution may not be unique. In this case, just output the smallest resulting number.

It is guaranteed that a solution exists.

Sample Input:

12
7 11
8 9
3 1
2 12
4 6
10 0
5 1
2 5
6 8
1 4
7 2
9 3

Sample Output:

359114268072

 

分析: 由于卡片编号与卡片数字不知道前后顺序,即第一个数既可能是编号,也有可能
 * 是卡片值;因此需要将两对数对都要保存下来;
 * 但是得注意卡片编号是从1到n进行编号的,当编号为i的卡片只可能有一张时,
 * 那么这张卡片必须属于编号为i的卡片,确定一张卡片以后(不妨设为 {id, val}
 * ,我们就需要将相应的val集合中为id值得卡片给删除掉,一张卡片只能使用一次,
 * 由于需要从集合中删除元素,而N得大小又是1e5,所以需要将删除操作控制在logN
 * 的时间复杂度内,因此卡片用set来存储,但是卡片可能有两张完全相同的数字,
 * (最多也只有两张),所以还需要用 multiset 来存储,对了,还有一个特点是从
 * 第i个集合中找出当前集合中最小的值,multiset自动递增排序,所以选用multiset
 * 是不得已,也是最佳的选择;
 * 当有两张完全相同的卡片的时候,当用完一张,不能将对边的值的集合中的此卡片给
 * 删除掉,因为一删除,就会将两张卡片都删除掉,因此还需要用一个map<PII, int> mp
 * 来记录每张卡片的值的张数。

解释的很糟糕吧,估计过一段时间我来看这段话,也要看半天才能看懂,但还是记录一下的。

/**
 * 由于卡片编号与卡片数字不知道前后顺序,即第一个数既可能是编号,也有可能
 * 是卡片值;因此需要将两对数对都要保存下来;
 * 但是得注意卡片编号是从1到n进行编号的,当编号为i的卡片只可能有一张时,
 * 那么这张卡片必须属于编号为i的卡片,确定一张卡片以后(不妨设为 {id, val}
 * ,我们就需要将相应的val集合中为id值得卡片给删除掉,一张卡片只能使用一次,
 * 由于需要从集合中删除元素,而N得大小又是1e5,所以需要将删除操作控制在logN
 * 的时间复杂度内,因此卡片用set来存储,但是卡片可能有两张完全相同的数字,
 * (最多也只有两张),所以还需要用 multiset 来存储,对了,还有一个特点是从
 * 第i个集合中找出当前集合中最小的值,multiset自动递增排序,所以选用multiset
 * 是不得已,也是最佳的选择;
 * 当有两张完全相同的卡片的时候,当用完一张,不能将对边的值的集合中的此卡片给
 * 删除掉,因为一删除,就会将两张卡片都删除掉,因此还需要用一个map<PII, int> mp
 * 来记录每张卡片的值的张数。
 * 
*/

#include <iostream>
#include <set>
#include <map>
#include <vector>

using namespace std;

typedef pair<int, int>PII;

const int N = 1e5+10;
multiset<int> st[N];
map<PII, int> ump;
bool hs[N];
vector<int> chk;

int main()
{
    int n;
    cin >> n;
    for(int i=0; i<n; ++i)
    {
        int u, v;
        scanf("%d%d", &u, &v);
        if(u > 0 && u <= n)
            st[u].insert(v);
        if(v > 0 && v <= n)
            st[v].insert(u);

        ump[{u, v}]++; //u,v卡片数目加一
        ump[{v, u}]++;
    }

    for(int i=1; i<=n; ++i)
        if(st[i].size() == 1)  //集合i只有一个元素
            chk.push_back(i);

    while(1)
    {
        vector<int> temp;
        if(temp.size()) break;
        for(auto ele : chk)
            if(hs[ele] == 0)
            {
                int v = *st[ele].begin();
                st[v].erase(ele);
                
                //集合v只有一个元素
                if(st[v].size() == 1)   temp.push_back(v);
                hs[ele] = 1; 
            }

        chk = temp;
        if(chk.empty()) break;
    }

    for(int i=1; i<=n; ++i)
    {
        int fs = *st[i].begin();
        printf("%d", fs);

        //当有两张完全相同的卡片的时候,当用完一张,不能将对边的
        //值的集合中的此卡片给删除掉,因为一删除,就会将两张卡片都
        //删除掉,因此还需要用一个map<PII, int> mp来记录每张卡片的
        //值的张数。
        if(ump[{fs, i}] == 1) 
        {
            st[fs].erase(i);
            
            //集合fs只有一个元素
            if(st[fs].size() == 1)
                chk.push_back(fs);
        }

        while(1)
        {
            vector<int> temp;
            if(temp.size()) break;

            for(auto ele : chk)
                if(hs[ele] == 0)
                {
                    int v = *st[ele].begin();
                    st[v].erase(ele);
                    if(st[v].size() == 1)   temp.push_back(v);
                    hs[ele] = 1;
                }

            chk = temp;
            if(chk.empty()) break;
        }
    }
    
    return 0;
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PAT甲级2023夏季考试题解(A-1 Trap,A-2 Queue Using Two Stacks,A-3 Rank of Binary Tree,A-4 Big Number) 的相关文章

  • 二进制方式部署k8s集群1.21版本-域名形式

    二进制方式部署k8s 1 21版本 域名形式 说明 系统参数 主机名称 IP地址 部署节点 部署组件 m1 192 168 11 187 k8s1 masterk8s2 master k8s1 etcd apiserver controll
  • 爬虫(五):python中的POST的四种请求方式(编码格式)

    POST请求主要包含json格式 xml格式 文件上传 form data 及默认传递的urlencoded HTTP的报文结构 1 请求行 请求方法 请求URL HTTP协议版本三个部分 2 请求头 从第二行开始到倒数第二行都是我们的请求
  • Clang之语法抽象树AST

    语法分析器的任务是确定某个单词流是否能够与源语言的语法适配 即设定一个称之为上下文无关语言 context free language 的语言集合 语法分析器建立一颗与 词法分析出的 输入单词流对应的正确语法树 语法分析树的建立过程主要有两

随机推荐

  • Nacos与Eureka的异同

    1 架构设计 Eureka采用CS架构 由服务注册中心Eureka Server和服务提供者 消费者Eureka Client组成 Nacos采用高可用的P2P设计 无主节点 所有的server节点都是同等作用 支持AP和CP两种模式 2
  • Android 自动获取经纬度,计算距离、经纬度、方位角

    最近做一个项目需要通过GPS获取经纬度 通过计算算出两点之间的距离 通过对Google和百度的疯狂轰炸 终于找到了解决的办法 首先声明权限 android name android permission ACCESS FINE LOCATI
  • Scrcpy视频同步源码分析

    什么是Scrcpy https github com Genymobile scrcpy Scrcpy是genymobile开源的一款手机镜像软件 通过对手机音视频的采集和同步 可以实现在PC平台上控制手机的功能 官方解释 此应用程序镜像通
  • PHP Drupal个人博客

    PHP Drupal个人博客 官网 Prerequisite PHP Composer 快速安装 composer create project drupal recommended project drupal cd drupal php
  • lucene 总体架构

    本文转载至 http www cnblogs com forfuture1978 archive 2009 12 14 1623596 html Lucene概述 一个高效的 可扩展的 全文检索库 全部用Java实现 无须配置 仅支持纯文本
  • 混合整数规划(Mixed Integer Programming)

    混合整数规划 Mixed Integer Programming 混合整数规划问题是运筹优化中经常遇到的一类问题 在这类问题中自变量的类型可能是整数也可能不是整数 相比于连续优化 混合整数规划很多时候会更难求解 在学术界混合整数规划一直是一
  • 最小生成树(普里姆算法和克鲁斯卡尔算法)

    1 基本介绍 2 普里姆算法 普里姆算法 package algorithm import java util Arrays public class PrimDemo public static final int MAX VALUE 1
  • 从p文件到m文件,快速将Matlab p代码转换成m文件

    你是否遇到过这样的问题 发现自己写的Matlab代码根本无法加密 或者别人发给你的MATLAB代码无法打开或运行 如果是这样 那么你需要一款强有力的Matlab解密工具 左左Matlab解密助手 左左解密助手是一款功能强大的Matlab解密
  • 状态机模型

    参考 什么是状态机 用C语言实现进程5状态模型 参考 设计模式 一目了然的状态机图 案例 状态模式 C语言实现 MP3播放 暂停案例 STM32按键消抖 入门状态机思维 常用的while循环内switch case形式 实现状态机的状态跳转
  • java自动化测试语言基础之正则表达式

    java自动化测试语言基础之正则表达式 文章目录 java自动化测试语言基础之正则表达式 Java 正则表达式 Java 正则表达式 正则表达式定义了字符串的模式 正则表达式可以用来搜索 编辑或处理文本 正则表达式并不仅限于某一种语言 但是
  • 树莓派 OCR识别 2-2:chineseocr_lite 部署

    chineseocr lite github项目地址 https github com ouyanghuiyu chineseocr lite 超轻量级中文ocr 支持竖排文字识别 支持ncnn推理 dbnet 1 8M crnn 2 5M
  • JAVA 获取某段时间内的所有日期集合

    集合里包含月份 开始 结束 2019 01 01 00 00 00 2019 01 31 23 59 00 2019 02 01 00 00 00 2019 02 28 23 59 00 2019 03 01 00 00 00 2019 0
  • 社区生鲜团购小程序

    摘 要 随着生活质量的提高 人们对生鲜购物体验的要求逐步升级 传统生鲜物流成本相对较高 生鲜产品品质控制困难 在新零售背景下的社区生鲜团购模式拥有经营成本低 用户黏性高等优点 互联网与实体店相结合带来了更多的便利和机会 自微信推出以来 就迅
  • 39. 组合总和 40. 组合总和 II

    39 组合总和 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target 找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 并以列表形式返回 你可以按 任意顺序 返回这些组合
  • Java文档注释用法+JavaDoc的使用详解

    Java文档注释 JavaDoc的使用详解 简介 文档注释负责描述类 接口 方法 构造器 成员属性 可以被JDK提供的工具 javadoc 所解析 自动生成一套以网页文件形式体现该程序说明文档的注释 注意 文档注释必须写在类 接口 方法 构
  • spring boot中使用@requestbody注解接收不到值是什么鬼

    首先 先科普一下这个注解的用法吧 requestbody一般是用于put或post请求时 在controller处接收前端发送的值 通过适当的HttpMessageConverter转换为JAVA类 而前端在发送值的时候必须指定数据是jso
  • “泰迪杯”超市Spark数据处理和数据分析项目实战Dataframe

    数据和代码 2019 年 泰迪杯 数据分析职业技能大赛 超市销售数据分析 一 背景 近年来 随着新零售业的快速发展 消费者购买商品时有了更多的对比和 选择 导致超市行业的竞争日益激烈 利润空间不断压缩 超市的经营管理产 生了大量数据 对这些
  • WINDOWS下使用redi并安装成系统服务开机启动

    WINDOWS下使用redis 下载redis源码 解压使用 将redis安装成window系统服务 不显示黑窗口 下载redis源码 linux下的redis可以再redis官网上找到Statble版本并下载 但是window版本在官网上
  • 实践练习三(可选):使用OBD 部署一个 三副本OceanBase 集群(离线安装)

    部署规划 这次作业是OceanBase 集群三节点部署方法 通过中控机直接远程登录到 OceanBase 节点上部署启动 observer 和 obproxy 进程 由于手上正好有7台物理机 所以在这个作业中会使用OBD直接部署为2 2 2
  • PAT甲级2023夏季考试题解(A-1 Trap,A-2 Queue Using Two Stacks,A-3 Rank of Binary Tree,A-4 Big Number)

    很幸运得到了一个满分 最后一题真的是连蒙带猜的AC的 当AC的那瞬间 可以用喜极而泣来形容了 去年十二月也参加了一次甲级 但是才考到89分 不是很满意 因此这次又去参加了一次 但总算得到了一点收获 也算对自己的一点安慰吧 A 1 Trap