PAT A Level(甲级) 秋季 2021年09月11日 题解

写在前面

所有题目大意和名字纯楼主脑记,准确还要看网上的题,但代码都没问题。
这次最大的问题竟然是读题不认真,7-1和7-3一直没过,后来看代码没问题,重新读题发现求的方向不对,改正后即A了。

7-1 Arrays and Linked Lists (20 分)

在这里插入图片描述

知识点:模拟

题意:

大致是描述了一种数据结构,是数组和链表的结合,告诉你几个顺序相连数组的初始地址和大小,然后查询编号是q的数字的地址,如果这个数组链表装不下,则输出
Illegal Access.
最后一行输出需要建立的数组的最小个数.

注意:

即使所有的查询都不成立,也要建立1个,因为最初至少有一个。

Simple Input:

6 7
2048 5
128 6
4016 10
1024 7
3072 12
9332 10
2 12 25 50 28 8 39

Simple Output:

2056
4020
1040
Illegal Access
3072
140
3116
5

代码:

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

struct node
{
    ll add;
    ll s;
};

vector<node>v;

int main()
{
    int n, k;
    scanf("%d %d", &n, &k);
    v.resize(n);
    ll sx = 0;
    for (int i = 0; i < n; ++i)
    {
        scanf("%lld %lld", &v[i].add, &v[i].s);
        sx += v[i].s;
    }
    set<int>s;
    ll mt = 0;
    for (int kk = 0; kk < k; ++kk)
    {
        ll q;
        scanf("%lld", &q);
        ll i = 0;
        ll sz = 0;
        if (q >= sx)
        {
            printf("Illegal Access\n");
            continue;
        }
        while (i < n && q >= sz)
        {
            sz += v[i].s;
            i++;
        }
        i -= 1;
        sz -= v[i].s;
        q -= sz;
        s.insert(i);
        mt = max(mt, i);
        printf("%lld\n", v[i].add + (ll)(q * 4));
    }
    printf("%lld", mt + 1);
    return 0;
}

7-2 Stack of Hats (25 分)

知识点:sort

题意:

一群PATer喜欢戴帽子,进餐馆后把脱下的帽子叠起来,像一个栈,希望你指出从上到下的帽子分别是几号人的. 已知体重越大戴的帽子越大.

注意:

你需要将体重排序,帽子size排序,然后每一位就对应起来,最后对帽子的顺序重新排序,就可以了.

代码:

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

struct node
{
    int pos;
    int p;
    int v;
};

bool cmp(node a, node b)
{
    return a.v < b.v;
}
bool cmp2(node a, node b)
{
    return a.p > b.p;
}

vector<node>v, a, v1, a1;

int main()
{
    int n;
    scanf("%d", &n);
    v.resize(n);
    a.resize(n);
    for (int i = 0; i < n; ++i)
    {
        scanf("%d", &v[i].v);
        v[i].p = i;
    }
    for (int i = 0; i < n; ++i)
    {
        scanf("%d", &a[i].v);
        a[i].p = i;
    }
    sort(a.begin(), a.end(), cmp);
    sort(v.begin(), v.end(), cmp);
    for (int i = 0; i < n; ++i)
    {
        v[i].pos = a[i].p + 1;
    }
    sort(v.begin(), v.end(), cmp2);
    for (int i = 0; i < n; ++i)
    {
        if (i != 0) printf(" ");
        printf("%d", v[i].pos);
    }
    return 0;
}

7-3 Playground Exploration (25 分)

知识点:DFS

题意:

在操场上有很多的点,一些点之间有路径连接,小朋友可以从任意一个点进入,并且每次会选择连通点中编号最小的作为下一个目标,以及不会去一个点两次,求从哪个点进入,可以玩的点最多,如果这样的点不止一个,就输出编号最小的点,并且输出从该点出发能经过最多的点数目.

注意:

DFS就能解决,注意存储的时候记得要每个节点的连通节点通过sort实现从小到大,而且如果通过此节点进入其中一个最小没有访问子节点,就不会访问其他子节点.

代码:

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

int edge[1001][1001];
vector<int>v[10001];
int mxs = -1;
int visit[10001] = { 0 };

void dfs(int s, int sp)
{
    int f = 0;
    visit[s] = 1;
    for (int i = 0; i < v[s].size(); ++i)
    {
        if (!visit[v[s][i]])
        {
            f = 1;
            dfs(v[s][i], sp + 1);
            return;
        }
    }
    if (mxs < sp)
    	mxs = sp;
    return;
}

int main()
{
    int n, m;
    scanf("%d %d", &n, &m);
    for (int i = 0; i < m; ++i)
    {
        int x, y;
        scanf("%d %d", &x, &y);
        v[x].push_back(y);
        v[y].push_back(x);
    }
    for (int i = 1; i <= n; ++i)
    {
        sort(v[i].begin(), v[i].end()); // 保证每个的子节点升序
    }
    vector<int>ans;
    int mx = -1;
    for (int i = 1; i <= n; ++i)
    {
        mxs = -1;
        memset(visit, 0, sizeof(visit));
        visit[i] = 1;
        dfs(i, 1);
        if (mx < mxs)
        {
            mx = mxs;
            ans.clear();
            ans.push_back(i);
        }
        else if (mx == mxs)
            ans.push_back(i);
    }
    sort(ans.begin(), ans.end());
    printf("%d %d", ans[0], mx);
    return 0;
}

7-4 Sorted Cartesian Tree (30 分)

知识点:小顶堆概念建树

题意:

一棵奇奇怪怪的树,树的节点都有 { key, priority },这棵树的中序遍历按照 key 的升序排列,并且 priority 形成一个小顶堆. 要求输出这棵树的层序遍历.

注意:

这个嘛,先根据 key 排序,得到中序遍历,然后利用小顶堆的性质 - 小顶堆的根比左右子树的任意一个值都小建树获取层序遍历,具体方式就是限定左右界限,在界限内找到最小值,作为小顶堆的根,然后通过根划分左右子树,分别递归,获取层序遍历.

代码:

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
struct node
{
    int k, p;
};
vector<node>v, h;
bool cmp(node a, node b)
{
    if (a.k != b.k)
    	return a.k < b.k;
    else
        return a.p < b.p; // 这个意义不大,感觉没有考到这一块,应该都是不同的数字
}
vector<node>level[100];
int mmx = -1;
void build(int l, int r, int lev)
{
    if (l > r) return;
    int mx = v[l].p;
    int t = l;
    for (int i = l; i <= r; ++i)
    {
        if (v[i].p < mx)
        {
            mx = v[i].p;
            t = i;
        }
    }
    level[lev].push_back(v[t]);
    mmx = max(lev, mmx);
    build(l, t - 1, lev + 1);
    build(t + 1, r, lev + 1);
    return;
}
int main()
{
    int n;
    scanf("%d", &n);
    v.resize(n + 1);
    for (int i = 1; i <= n; ++i)
    {
        scanf("%d %d", &v[i].k, &v[i].p);
    }
    sort(v.begin() + 1, v.end(), cmp);
    build(1, n, 0);
    for (int i = 0; i <= mmx; ++i)
    {
        for (int j = 0; j < level[i].size(); ++j)
        {
            if (!(i == 0 && j == 0)) printf(" ");
            printf("%d", level[i][j].k);
        }
    }
    printf("\n");
    for (int i = 0; i <= mmx; ++i)
    {
        for (int j = 0; j < level[i].size(); ++j)
        {
            if (!(i == 0 && j == 0)) printf(" ");
            printf("%d", level[i][j].p);
        }
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
2021数学建模E题是关于自动调节系统的稳态误差问题。解题思路如下: 首先,我们需要了解自动调节系统的基本原理。自动调节系统通过测量输出信号与期望信号之间的差异,采取一系列措施来调整系统的输入信号,以实现系统输出与期望信号的一致性。其中,稳态误差是指系统在稳定状态时,输出信号与期望信号之间的残差。 针对这个问题,我们可以采用控制理论中的PID控制器进行建模和分析。PID控制器包含比例项、积分项和微分项,可以根据误差信号的大小、变化率和积分,调节系统的输入信号。 首先,我们需要建立自动调节系统的数学模型。可以考虑使用差分方程描述系统的动态行为,利用系统的输入与输出之间的关系来建立模型。然后,可以根据模型参数和系统的特性,计算出稳态误差。 接下来,我们可以通过调节PID控制器的参数来减小稳态误差。常见的方法是通过调整比例增益、积分时间常数和微分时间常数来实现。可以利用数学方法,例如反馈控制理论和优化算法,确定最佳的参数取值,以达到最小的稳态误差。 最后,我们可以通过数值模拟和仿真来验证建立的数学模型和参数调节的有效性。可以利用计算机软件,例如MATLAB,进行仿真实验,观察系统的稳态误差情况。根据仿真结果,可以进一步优化参数,以获得更好的控制效果。 总之,2021数学建模E题的解题思路是建立自动调节系统的数学模型,并利用PID控制器的参数调节来减小稳态误差。通过数值模拟和仿真实验验证模型的有效性。这样可以解决自动调节系统的稳态误差问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值