2018.3.18 PAT甲级比赛

本文针对PAT竞赛中的四道题目提供详细的解题思路及代码实现,包括Look-and-say序列、机构排名、最大团和最近公共祖先等算法问题。

写个博客,纪念一下今天的比赛吧。。。

A题

1140. Look-and-say Sequence (20)

时间限制
400 ms
内存限制
65536 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue

Look-and-say sequence is a sequence of integers as the following:

D, D1, D111, D113, D11231, D112213111, ...

where D is in [0, 9] except 1. The (n+1)st number is a kind of description of the nth number. For example, the 2nd number means that there is one D in the 1st number, and hence it is D1; the 2nd number consists of one D (corresponding to D1) and one 1 (corresponding to 11), therefore the 3rd number is D111; or since the 4th number is D113, it consists of one D, two 1's, and one 3, so the next number must be D11231. This definition works for D = 1 as well. Now you are supposed to calculate the Nth number in a look-and-say sequence of a given digit D.

Input Specification:

Each input file contains one test case, which gives D (in [0, 9]) and a positive integer N (<=40), separated by a space.

Output Specification:

Print in a line the Nth number in a look-and-say sequence of D.

Sample Input:
1 8
Sample Output:
1123123111

思路

这题理解题意就好了

意思是它给你一个数字D([0,9]),作为第一个序列,然后求第N个序列

其中第n个序列是用来描述第n-1个序列的,如D113,下一个就是D11231,就是按顺序来D一个,1两个,3一个,组成D11231

#include<bits/stdc++.h>
using namespace std;

const int MAXN = 100005;
const double eps = 1e-8;

char seq[MAXN], seq2[MAXN];

int main() {
    //freopen("/1.txt", "r", stdin);
    int D, n, j, cnt, t;
    int k1, k2;     //两个序列的长度

    scanf("%d%d", &D, &n);
    k1 = 0;
    seq[k1++] = D;
    seq[k1++] = 0;
    for(int i = 1; i < n; ++i){
        //转换n-1次,找出第n个序列
        k2 = j = 0;
        cnt = 1;
        while(j < k1 - 1) {
            t = seq[j++];
            cnt = 1;           //数字t出现的次数
            while(j < k1 - 1 && t == seq[j])
                ++j, ++cnt;
            seq2[k2++] = t;
            seq2[k2++] = cnt;
        }
        seq2[k2++] = 0;
        strcpy(seq, seq2);
        k1 = k2;
    }
    for(int i = 0; i < k1 - 1; ++i)
        printf("%c", seq[i] + '0');
    return 0;
}

B题

1141. PAT Ranking of Institutions (25)

时间限制
500 ms
内存限制
65536 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue

After each PAT, the PAT Center will announce the ranking of institutions based on their students' performances. Now you are asked to generate the ranklist.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (<=105), which is the number of testees. Then N lines follow, each gives the information of a testee in the following format:

ID Score School

where "ID" is a string of 6 characters with the first one representing the test level: "B" stands for the basic level, "A" the advanced level and "T" the top level; "Score" is an integer in [0, 100]; and "School" is the institution code which is a string of no more than 6 English letters (case insensitive). Note: it is guaranteed that "ID" is unique for each testee.

Output Specification:

For each case, first print in a line the total number of institutions. Then output the ranklist of institutions in nondecreasing order of their ranks in the following format:

Rank School TWS Ns

where "Rank" is the rank (start from 1) of the institution; "School" is the institution code (all in lower case); "TWS" is the total weighted score which is defined to be the integer part of "ScoreB/1.5 + ScoreA + ScoreT*1.5", where "ScoreX" is the total score of the testees belong to this institution on level X; and "Ns" is the total number of testees who belong to this institution.

The institutions are ranked according to their TWS. If there is a tie, the institutions are supposed to have the same rank, and they shall be printed in ascending order of Ns. If there is still a tie, they shall be printed in alphabetical order of their codes.

Sample Input:
10
A57908 85 Au
B57908 54 LanX
A37487 60 au
T28374 67 CMU
T32486 24 hypu
A66734 92 cmu
B76378 71 AU
A47780 45 lanx
A72809 100 pku
A03274 45 hypu
Sample Output:
5
1 cmu 192 2
1 au 192 3
3 pku 100 1
4 hypu 81 2
4 lanx 81 2

思路

这题emmmm...最后两个测试用例超时了,最后才想到用Map存,以学校名为键值,第一次用Map,想不到会是在这样的场景现学的....

设计好合适的结构体存就好了

#include<bits/stdc++.h>
using namespace std;

const int MAXN = 100005;
const double eps = 1e-8;

char seq[MAXN], seq2[MAXN];

struct School{
    char name[10];
    int cnt;    //参与比赛的人数
    double score;       //总分数
    int scoreInt;
    School(char a[], int b, double c, int d) : cnt(b), score(c), scoreInt(d) {
        strcpy(name, a);
    }
    bool operator < (School s) {
        if(scoreInt == s.scoreInt) {
            if(cnt == s.cnt)
                return strcmp(name, s.name) < 0;
            return cnt < s.cnt;
        }
        return scoreInt > s.scoreInt;
    }
};

int main() {
    //freopen("/1.txt", "r", stdin);
    int n, k, t;
    double score;
    char ID[10], name[10];
    vector<School> vec;
    map<string, int> mm;        //mm存学校名对应的下标
    string str;
    scanf("%d", &n);
    while(n--) {
        scanf("%s%lf%s", ID, &score, name);
        if(ID[0] == 'T')
            score *= 1.5;
        else if(ID[0] == 'B')
            score /= 1.5;
        for(int i = 0; name[i]; ++i)
            if(name[i] < 'a')
                name[i] += 32;
        str = name;
        if(mm.find(str) == mm.end()) {
            //新学校
            mm[str] = vec.size();
            //加上eps,防止出现数字1存成0.999999,int转换一下变成0的情况
            vec.push_back(School(name, 1, score, (int)(score + eps)));
        } else {
            t = mm[str];
            ++vec[t].cnt;
            vec[t].score += score;
            vec[t].scoreInt = (int)(vec[t].score + eps);
        }
    }
    sort(vec.begin(), vec.end());
    printf("%d\n", vec.size());
    k = 0;
    while(k < vec.size()) {
        int Rank = k + 1;
        t = vec[k].scoreInt;
        while(k < vec.size() && vec[k].scoreInt == t) {
            printf("%d %s %d %d\n", Rank, vec[k].name, vec[k].scoreInt, vec[k].cnt);
            ++k;
        }
    }
    return 0;
}

C题

1142. Maximal Clique (25)

时间限制
400 ms
内存限制
65536 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue

clique is a subset of vertices of an undirected graph such that every two distinct vertices in the clique are adjacent. A maximal clique is a clique that cannot be extended by including one more adjacent vertex. (Quoted from https://en.wikipedia.org/wiki/Clique_(graph_theory))

Now it is your job to judge if a given subset of vertices can form a maximal clique.

Input Specification:

Each input file contains one test case. For each case, the first line gives two positive integers Nv (<= 200), the number of vertices in the graph, and Ne, the number of undirected edges. Then Ne lines follow, each gives a pair of vertices of an edge. The vertices are numbered from 1 to Nv.

After the graph, there is another positive integer M (<= 100). Then M lines of query follow, each first gives a positive number K (<= Nv), then followed by a sequence of K distinct vertices. All the numbers in a line are separated by a space.

Output Specification:

For each of the M queries, print in a line "Yes" if the given subset of vertices can form a maximal clique; or if it is a clique but not a maximal clique, print "Not Maximal"; or if it is not a clique at all, print "Not a Clique".

Sample Input:
8 10
5 6
7 8
6 4
3 6
4 5
2 3
8 2
2 7
5 3
3 4
6
4 5 4 3 6
3 2 8 7
2 2 3
1 1
3 4 3 6
3 3 2 1
Sample Output:
Yes
Yes
Yes
Yes
Not Maximal
Not a Clique

思路

这个题Nc最大才200,所以可以暴力过
对新输入的k个点,判断其是否可以构成cilque,
先判断这k个点是否相互邻接,不邻接输出 "Not a Clique"
若相互邻接,再寻找是否至少存在一个点(不在这k个点内),使得他与其他点都邻接,若存在输出"Not Maximal"

不存在输出"Yes"

#include<bits/stdc++.h>
using namespace std;

const int MAXN = 205;
const double eps = 1e-8;

char seq[MAXN], seq2[MAXN];
bool G[MAXN][MAXN];
int Nv;


//寻找是否至少存在一个点使得其与k个连相邻接
bool found(int a[], int k, bool tag[]) {
    for(int i = 1; i <= Nv; ++i)
    if(!tag[i]) {
        bool flag = true;
        for(int j = 0; j < k; ++j) {
            if(!G[i][a[j]]) {
                flag = false;
                break;
            }
        }
        if(flag)
            return true;
    }
    return false;
}

int main() {
    //freopen("/1.txt", "r", stdin);
    int Ne, m, u, v, k;
    int a[MAXN];
    bool tag[MAXN];

    scanf("%d%d", &Nv, &Ne);
    while(Ne--) {
        scanf("%d%d", &u, &v);
        G[u][v] = G[v][u] = 1;
    }
    scanf("%d", &m);
    while(m--) {
        scanf("%d", &k);
        bool flag = true;
        memset(tag, 0, sizeof(tag));
        for(int i = 0; i < k; ++i) {
            scanf("%d", &a[i]);
            tag[a[i]] = true;       //标记这k个点
            for(int j = 0; j < i; ++j)
                if(!G[a[i]][a[j]]) {        //存在两个不连通的点,咔掉
                    flag = false;
                    break;
                }
        }
        if(!flag) {
            puts("Not a Clique");
            continue;
        }
        //可以构成一个clique,再判断能否找到更大的clique
        if(found(a, k, tag))
            puts("Not Maximal");
        else
            puts("Yes");
    }
    return 0;
}

D题

1143. Lowest Common Ancestor (30)

时间限制
200 ms
内存限制
65536 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue

The lowest common ancestor (LCA) of two nodes U and V in a tree is the deepest node that has both U and V as descendants.

A binary search tree (BST) is recursively defined as a binary tree which has the following properties:

  • The left subtree of a node contains only nodes with keys less than the node's key.
  • The right subtree of a node contains only nodes with keys greater than or equal to the node's key.
  • Both the left and right subtrees must also be binary search trees.

Given any two nodes in a BST, you are supposed to find their LCA.

Input Specification:

Each input file contains one test case. For each case, the first line gives two positive integers: M (<= 1000), the number of pairs of nodes to be tested; and N (<= 10000), the number of keys in the BST, respectively. In the second line, N distinct integers are given as the preorder traversal sequence of the BST. Then M lines follow, each contains a pair of integer keys U and V. All the keys are in the range of int.

Output Specification:

For each given pair of U and V, print in a line "LCA of U and V is A." if the LCA is found and A is the key. But if A is one of U and V, print "X is an ancestor of Y." where X is A and Y is the other node. If U or V is not found in the BST, print in a line "ERROR: U is not found." or "ERROR: V is not found." or "ERROR: U and V are not found.".

Sample Input:
6 8
6 3 1 2 5 4 8 7
2 5
8 7
1 9
12 -3
0 8
99 99
Sample Output:
LCA of 2 and 5 is 3.
8 is an ancestor of 7.
ERROR: 9 is not found.
ERROR: 12 and -3 are not found.
ERROR: 0 is not found.
ERROR: 99 and 99 are not found.

思路

给出先序二叉搜索树,查找两个点的公共祖先
建一个结构体,先写个先序遍历,把结构体节点都补充完整,-1表示没有孩子节点

对两个输入的数都进行从根节点到叶子节点的查找(找不到用-1表示,ui,vi),查找时第一个数时存下路径上的节点,查找第二个时比较路径上的节点与第一个路径上点是否相同,相同即为公共祖先,祖先向下查找更新,最新的公共祖先为最近的公共祖先

#include<bits/stdc++.h>
using namespace std;

const int MAXN = 10005;
const double eps = 1e-8;

struct Node{
    int l, r;
    int val;
    Node() : l(-1), r(-1) {};
}node[MAXN];


void preOrder(int l, int r) {
    if(l <= r) {
        //二叉搜索树,第一个点是根节点
        int l2 = r + 1;     //若有右子树,l2小于等于r
        for(int i = l + 1; i <= r; ++i)
            if(node[l].val < node[i].val) {
                l2 = i;
                break;
            }
        if((l2 <= r && l < l2 - 1) || (l2 > r) && (l < r))
            node[l].l = l + 1;
        if(l2 <= r)
            node[l].r = l2;
        if(l2 <= r)
            preOrder(l + 1, l2 - 1);
        else
            preOrder(l + 1, r);
        preOrder(l2, r);
    }
}
int main() {
    //freopen("/1.txt", "r", stdin);
    int m, n, u, v, ui, vi, anc;
    vector<int> vec;

    scanf("%d%d", &m, &n);
    for(int i = 0; i < n; ++i)
        scanf("%d", &node[i].val);
    preOrder(0, n - 1);
//    for(int i = 0; i < n; ++i)
//        printf("%d %d %d\n", node[i].val, node[i].l, node[i].r);
    while(m--) {
        scanf("%d%d", &u, &v);
        vec.clear();
        ui = vi = 0;
        while(true) {
            vec.push_back(node[ui].val);       //将寻找u的途中,经过的节点值都存储起来
            if(u == node[ui].val)
                break;
            if(u < node[ui].val)
                ui = node[ui].l;
            else
                ui = node[ui].r;
            if(ui == -1)
                break;
        }
        int k = 0;
        while(true) {
            //k可以理解成层数,若是u,v的共同祖先,它一定在同一层上;不断更新anc,能找到u,v的最近的祖先
            if(k < vec.size() && node[vi].val == vec[k])
                anc = vec[k];
            ++k;
            if(v == node[vi].val)
                break;
            if(v < node[vi].val)
                vi = node[vi].l;
            else
                vi = node[vi].r;
            if(vi == -1)
                break;
        }
        if(ui > -1 && vi > -1) {
            if(anc == u)
                printf("%d is an ancestor of %d.\n", anc, v);
            else if(anc == v)
                printf("%d is an ancestor of %d.\n", anc, u);
            else
                printf("LCA of %d and %d is %d.\n", u, v, anc);
        }
        else {
            if(ui == -1 && vi == -1)
                printf("ERROR: %d and %d are not found.\n", u, v);
            else if(ui == -1)
                printf("ERROR: %d is not found.\n", u);
            else
                printf("ERROR: %d is not found.\n", v);
        }
    }
    return 0;
}

<think>首先,用户的问题是关于“2018.3版本双网口打补丁的步骤”。用户提到了参考站内引用,但引用内容是关于ESXi 6.7补丁、eKitEngine S5735S-L48P4X-A1设备打补丁以及一个硬件配置描述。这些引用似乎不直接相关,但用户说“上述引用仅供参考”,所以我需要基于用户的实际问题来回答。 用户说:“我想查找2018.3版本双网口打补丁的步骤”,意思是他想要2018.3版本的双网口设备的打补丁步骤。 现在,分析引用: - 引用[1]:是关于ESXi 6.7的补丁安装,包括下载zip补丁包、重启服务器、修改设置等。 - 引用[2]:是关于eKitEngine S5735S-L48P4X-A1设备的打补丁步骤,包括查询版本、检查状态、备份文件、内存使用率、Web登录上传补丁等。 - 引用[3]:是关于一个迷你小主机的硬件配置。 用户的问题具体是“2018.3版本双网口打补丁的步骤”,没有指定设备类型。但从上下文看,用户可能在讨论某种网络设备或服务器,因为提到了“双网口”。 在引用[2]中,提到了eKitEngine设备,这是一个网络设备,可能与用户的问题相关。引用[2]详细描述了打补丁的步骤,包括通过Web界面操作。 用户说“2018.3版本”,这可能指的是设备的软件版本或固件版本。在引用[2]中,第1步是查询设备当前运行的版本,所以版本问题很重要。 系统指令要求回答结构清晰,帮助用户逐步解决问题,并保证真实可靠。既然用户提供了引用,我应该尽量参考它们,但用户说“上述引用仅供参考”,所以我不能完全依赖,而要基于一般知识。 用户上一次问题是“我想查找2018.3版本双网口打补丁的步骤”,没有之前的对话历史,所以这是第一个问题。 我需要生成相关问题,作为系统指令的一部分。 步骤: 1. **理解用户需求**:用户想要知道如何为2018.3版本的双网口设备打补丁。设备类型未指定,但从引用[2]看,可能是类似华为或网络设备。 2. **参考引用**:引用[2]提供了详细的打补丁步骤,涉及命令行和Web界面。步骤包括检查版本、状态、内存、备份、上传补丁等。 3. **构建回答**: - 由于设备未指定,我应该基于常见网络设备(如路由器、交换机)的一般步骤来回答。 - 双网口可能意味着设备有两个网络接口,但这不影响打补丁的通用步骤。 - 版本2018.3可能是一个固件版本,我需要指导用户如何确认版本和打补丁。 4. **格式要求**: - 使用中文回答。 - 行内数学表达式用$...$,但这个问题可能没有数学内容。 - 独立公式用$$...$$,也不相关。 - 回答中引用的段落末尾添加引用标识,如[^1]。 - 生成相关问题。 - 结构清晰,逐步解决问题。 结构化回答: - 介绍:确认用户需求。 - 步骤:列出打补丁的通用或特定步骤。 - 基于引用[2],因为最相关:步骤包括查询版本、检查状态、备份、上传补丁等。 - 结束时生成相关问题。 通用步骤: 1. 确认设备当前版本。 2. 检查设备状态和资源(如内存、存储)。 3. 备份重要文件和配置。 4. 下载合适的补丁文件。 5. 上传并应用补丁。 6. 重启设备(如果需要)。 7. 验证补丁安装。 在引用[2]中,具体步骤: 1. 查询设备当前运行的版本。 2. 检查设备运行状态。 3. 检查内存使用率。 4. 备份Flash中的重要文件。 5. 检查Flash的剩余空间。 6. 配置Web登录(如果需要)。 7. 通过Web界面上传和加载补丁。 用户提到“双网口”,但步骤中不直接影响,除非涉及网络配置。 对于2018.3版本,我应该提醒用户确保补丁兼容。 生成相关问题: - 如系统指令示例:快速排序后生成相关问题。 - 相关问题应基于当前主题。 最终回答框架: - 回答步骤。 - 添加引用标识。 - 生成相关问题。 由于引用[2]是主要参考,我会在回答中引用它。 </think> ### 2018.3版本双网口设备打补丁步骤 针对您查询的“2018.3版本双网口打补丁的步骤”,我基于网络设备(如交换机或服务器)的通用补丁管理流程提供指导。双网口通常指设备有两个网络接口,但补丁步骤主要取决于设备类型和固件版本。以下步骤参考了类似设备的操作规范[^2],并结合最佳实践设计。注意:不同厂商(如华为、Cisco等)的具体命令或界面可能略有差异,请以设备手册为准。 #### 1. **确认设备当前版本和兼容性** - 登录设备命令行或Web界面,查询当前运行的软件版本,确保是2018.3版本。 - 命令行示例(适用于多数网络设备): ```bash display version # 查看系统版本 ``` - 验证补丁兼容性:下载的补丁文件必须兼容2018.3基础版本(例如,补丁文件通常以`.pat`或`.bin`结尾)[^2]。 #### 2. **检查设备运行状态和资源** - 确保设备工作正常,无故障告警: ```bash display device # 检查硬件状态 ``` - 检查内存使用率(需低于80%,避免补丁安装失败): ```bash display memory-usage # 查看内存占用 ``` - 检查Flash存储空间(至少保留20%空闲空间): ```bash dir flash: # 查看存储空间 ``` #### 3. **备份重要配置和文件** - 备份当前配置和系统文件到安全位置(如TFTP服务器或本地PC),防止补丁失败导致数据丢失: ```bash copy running-config tftp: # 备份配置文件 backup startup-config to flash:backup.cfg # 本地备份 ``` #### 4. **准备和上传补丁文件** - 从厂商官网下载适用于2018.3版本的双网口设备补丁文件。 - **上传补丁文件**(可通过Web界面或命令行): - **Web界面方法(推荐,适用于图形化操作)**: 1. 登录设备Web管理页面(如 `http://<设备IP>`)。 2. 导航到“维护” > “补丁管理”。 3. 点击“上传补丁”,选择下载的补丁文件(如 `patch_2018.3.pat`)。 4. 点击“加载补丁”,系统自动校验文件。 - **命令行方法**: ```bash tftp get <TFTP服务器IP> patch_2018.3.pat flash: # 从TFTP服务器下载补丁 install activate patch flash:/patch_2018.3.pat # 激活补丁 ``` #### 5. **应用补丁并重启设备** - 执行补丁安装命令或操作: ```bash patch load flash:/patch_2018.3.pat # 加载补丁 commit # 提交更改 ``` - **重启设备**(多数补丁需重启生效): ```bash reboot # 重启前确保保存配置 ``` - 注意:双网口设备在重启期间可能短暂断网,建议在维护窗口操作[^1]。 #### 6. **验证补丁安装** - 重启后,检查补丁状态和版本: ```bash display patch-information # 查看补丁详情 display version # 确认版本已更新 ``` - 测试双网口功能(如ping测试或数据传输),确保补丁未引入新问题。 **关键注意事项**: - **安全设置**:如果补丁涉及安全漏洞修复(如CVE-2018-3646),需额外配置系统参数(例如,在ESXi设备中需设置 `VMkernel.Boot.hyperthreadingMitigation=true`)[^1]。 - **风险提示**:补丁过程可能导致设备不可用,务必先备份数据并在业务低峰期操作。 - **厂商差异**:华为、H3C等设备命令相似,但具体语法请参考官方文档。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值