2018.9.8pat秋季甲级考试

第一次参加pat考试,结果很惨,只做了中间两道题,还有一个测试点错误,所以最终只得了不到50分。题目是甲级练习题的1148-1151。

考试时有些紧张,第一题第二题开始测试样例都运行不正确,但是调试程序考场的vs2013不能粘贴,还得一点点输上去。浪费了很多时间。

1、Werewolf - Simple Version

之前遇到这种题目较少,所以刚开始没什么思路。后来想到的方法是假设撒谎的两个人分别是i、j,然后遍历所有i、j,找出符合条件的。当时总共用了得有一个小时,但程序一直得不到正确答案,只好放弃。后来回到学校去调试程序发现问题出现在一个continue上,continue后面有一个操作需要完成但直接跳过了。但是按这个方法最后一个测试点错误。

其实这类题目问的是什么就假设什么,然后遍历所有可能性找出符合条件的就行。因此正确做法是直接假设两个狼人为i、j就行。

 1 #include <iostream>
 2 using namespace std;
 3
 4 int a[101], N;
 5 int main()
 6 {
 7     int i, j, k, t;
 8     cin >> N;
 9     for (i = 1; i <= N; i++) cin >> a[i];
10     for (i = 1; i <= N; i++)
11     {
12         for (j = i + 1; j <= N; j++)
13         {
14             bool b[101] = {};
15             b[i] = b[j] = 1;
16             int lie1, lie2, cnt = 0;
17             for (k = 1; k <= N; k++)
18             {
19                 if (a[k] > 0 && b[a[k]] || a[k] < 0 && !b[-a[k]])
20                 {
21                     cnt++;
22                     if (cnt == 1) lie1 = k;
23                     if (cnt == 2) lie2 = k;
24                 }
25             }
26             if (cnt == 2 && b[lie1] != b[lie2])
27             {
28                 printf("%d %d", i, j);
29                 return 0;
30             }
31         }
32     }
33     printf("No Solution");
34     return 0;
35 }

2、Dangerous Goods Packaging

这道题比较简单,但是考试时一开始思路不对,我用的是一个数组保存每一个编号不能放到一块的编号。但是每一个编号可能和多个编号不能放到一块,因此用set存储每一个编号的互斥编号。

 1 #include <iostream>
 2 #include <map>
 3 #include <set>
 4 using namespace std;
 5
 6 int main()
 7 {
 8     int N, M;
 9     cin >> N >> M;
10     map<int, set<int>> mp;
11     int i, a, b;
12     for (i = 0; i < N; i++)
13     {
14         cin >> a >> b;
15         mp[a].insert(b);
16         mp[b].insert(a);
17     }
18     int K, j;
19     for (i = 0; i < M; i++)
20     {
21         cin >> K;
22         set<int> st;
23         bool flag = true;
24         for (j = 0; j < K; j++)
25         {
26             cin >> a;
27             if (!flag) continue;
28             if (mp.find(a) != mp.end())
29             {
30                 for (int t : mp[a])
31                 {
32                     if (st.find(t) != st.end()) flag = false;
33                 }
34             }
35             st.insert(a);
36         }
37         printf("%s\n", flag ? "Yes" : "No");
38     }
39     return 0;
40 }

3、Travelling Salesman Problem

这道题也不难,但是考试时有一个测试点错误,回学校后再看时发现是判断时少了一个条件,即TS cycle和TS simple cycle都要经过所有顶点。

当路径上有不相邻的顶点或者路径的首尾顶点不相连或不经过所有顶点时,Not a TS cycle。否则路径上除了最后一个顶点外有重复的顶点就是TS cycle,否则就是TS simple cycle。

 1 #include <iostream>
 2 using namespace std;
 3
 4 int G[201][201];
 5
 6 int main()
 7 {
 8     int N, M;
 9     cin >> N >> M;
10     int v, w, d, i;
11     for (i = 0; i < M; i++)
12     {
13         cin >> v >> w >> d;
14         G[v][w] = G[w][v] = d;
15     }
16     int K, n, j, first, minId, min = 99999999;
17     cin >> K;
18     for (i = 1; i <= K; i++)
19     {
20         bool na = false, simple = true, allOccured = true;
21         bool occur[201] = {};
22         int sum = 0;
23         cin >> n >> first;
24         v = first;
25         occur[first] = true;
26         for (j = 1; j < n; j++)
27         {
28             cin >> w;
29             sum += G[v][w];
30             if (G[v][w] == 0) na = true;
31             if (occur[w] && j != n - 1) simple = false;
32             occur[w] = true;
33             v = w;
34         }
35         for (j = 1; j <= N; j++)
36         {
37             if (!occur[j]) allOccured = false;
38         }
39         printf("Path %d: ", i);
40         if (na) printf("NA ");
41         else printf("%d ", sum);
42         if (v != first || na || !allOccured) printf("(Not a TS cycle)\n");
43         else
44         {
45             if (simple) printf("(TS simple cycle)\n");
46             else printf("(TS cycle)\n");
47             if (sum < min)
48             {
49                 min = sum;
50                 minId = i;
51             }
52         }
53     }
54     printf("Shortest Dist(%d) = %d", minId, min);
55     return 0;
56 }

4、LCA in a Binary Tree

这道题开始一看还以为是原题,就按照二叉搜索树去做,最后运行结果不正确才发现题目说的是二叉树,不是二叉搜索树。但已经没时间了。

后来我用的方法是,先建树,然后求出顶点到两个节点的路径,把两个路径从前往后比较,第一个不相同结点的前一个结点就是LCA。

 1 #include <iostream>
 2 #include <set>
 3 #include <vector>
 4 using namespace std;
 5
 6 typedef struct Node *Tree;
 7 struct Node
 8 {
 9     int data;
10     Tree left, right;
11 }*root;
12
13 vector<int> in, pre;
14 Tree buildTree(Tree T, int begin, int end, int root);
15 int ancestor(int u, int v);
16 bool path(Tree T, int a, vector<int>& v);
17
18 int main()
19 {
20     int M, N, i;
21     cin >> M >> N;
22     in.resize(N);
23     pre.resize(N);
24     set<int> st;
25     for (i = 0; i < N; i++) cin >> in[i];
26     for (i = 0; i < N; i++)
27     {
28         cin >> pre[i];
29         st.insert(pre[i]);
30     }
31     root = NULL;
32     root = buildTree(root, 0, N - 1, 0);
33     int u, v;
34     for (i = 0; i < M; i++)
35     {
36         cin >> u >> v;
37         bool b1 = (st.find(u) == st.end());
38         bool b2 = (st.find(v) == st.end());
39         if (b1 && b2) printf("ERROR: %d and %d are not found.", u, v);
40         else if (b1 || b2) printf("ERROR: %d is not found.", b1 ? u : v);
41         else {
42             int anc = ancestor(u, v);
43             if (anc == u) printf("%d is an ancestor of %d.", u, v);
44             else if (anc == v) printf("%d is an ancestor of %d.", v, u);
45             else printf("LCA of %d and %d is %d.", u, v, anc);
46         }
47         printf("\n");
48     }
49     return 0;
50 }
51
52 Tree buildTree(Tree T, int begin, int end, int root)
53 {
54     if (begin > end) return NULL;
55     T = new Node;
56     T->data = pre[root];
57     T->left = T->right = NULL;
58     int p;
59     for (p = begin; p <= end; p++)
60     {
61         if (in[p] == pre[root]) break;
62     }
63     T->left = buildTree(T->left, begin, p - 1, root + 1);
64     T->right = buildTree(T->right, p + 1, end, root + p - begin + 1);
65     return T;
66 }
67
68 int ancestor(int u, int v)
69 {
70     vector<int> p1, p2;
71     bool b1 = path(root, u, p1);
72     bool b2 = path(root, v, p2);
73     int i;
74     for (i = 0; i < p1.size() && i < p2.size() && p1[i] == p2[i]; i++);
75     if (i == p1.size()) return p1[i - 1];
76     if (i == p2.size()) return p2[i - 1];
77     return p1[i - 1];
78 }
79
80 bool path(Tree T, int a, vector<int>& v)
81 {
82     if (T == NULL) return false;
83     v.push_back(T->data);
84     if (T->data == a) return true;
85     bool b1 = path(T->left, a, v);
86     if (b1) return true;
87     bool b2 = path(T->right, a, v);
88     if (!b1 && !b2)
89     {
90         v.pop_back();
91         return false;
92     }
93     return true;
94 }

看柳婼的博客学会了较简单的方法:先把每个结点在中序遍历中的位置记录下来,然后递归时根据u,v和当前root在中序遍历中的位置就可以知道u和v是在当前结点左子树还是右子树。

 1 #include <iostream>
 2 #include <map>
 3 #include <vector>
 4 using namespace std;
 5
 6 vector<int> in, pre;
 7 map<int, int> mp;
 8
 9 void lca(int left, int right, int root, int u, int v);
10
11 int main()
12 {
13     int M, N, i;
14     cin >> M >> N;
15     in.resize(N + 1);
16     pre.resize(N + 1);
17     for (i = 1; i <= N; i++)
18     {
19         cin >> in[i];
20         mp[in[i]] = i;
21     }
22     for (i = 1; i <= N; i++) cin >> pre[i];
23     int u, v;
24     for (i = 0; i < M; i++)
25     {
26         cin >> u >> v;
27         if (mp[u] == 0 && mp[v] == 0) printf("ERROR: %d and %d are not found.\n", u, v);
28         else if (mp[u] == 0 || mp[v] == 0) printf("ERROR: %d is not found.\n", mp[u] ? v : u);
29         else lca(1, N, 1, u, v);
30     }
31     return 0;
32 }
33
34 void lca(int left, int right, int root, int u, int v)
35 {
36     if (left > right) return;
37     int pU = mp[u], pV = mp[v], pRoot = mp[pre[root]];
38     if (pU < pRoot && pV < pRoot)
39         lca(left, pRoot - 1, root + 1, u, v);
40     else if (pU < pRoot && pV > pRoot || pU > pRoot && pV < pRoot)
41         printf("LCA of %d and %d is %d.\n", u, v, pre[root]);
42     else if (pU > pRoot && pV > pRoot)
43         lca(pRoot + 1, right, root + pRoot - left + 1, u, v);
44     else if (pU == pRoot)
45         printf("%d is an ancestor of %d.\n", u, v);
46     else if (pV == pRoot)
47         printf("%d is an ancestor of %d.\n", v, u);
48 }

参加这次考试只能说明自己很菜,解题速度比较慢;审题不仔细,比如第二题开始用的一个数组去存储每个编号的互斥编号;写代码容易出现很多问题,比如第一题continue导致逻辑出现错误。

正在准备考研,时间很紧张,只能周末抽时间刷几道题,12月份冬季再参加一次。

原文地址:https://www.cnblogs.com/lxc1910/p/9650935.html

时间: 2024-11-06 11:37:14

2018.9.8pat秋季甲级考试的相关文章

2018年四川理工学院软件工程考试大纲(软件测试)

2018年四川理工学院软件工程考试大纲(软件测试)   1.软件测试的概念.目的 软件测试就是软件在投入运行前,对软件的需求分析.设计规格说明和编码的最终复审,是软件质量保证的关键步骤 软件测试是为了发现错误而执行程序的过程 软件测试的目的是为了找出软件中潜在的各种错误和缺陷 2.调试是指 调试是对测试发现的错误进行纠错的过程 3.软件测试的分类 Ⅰ(按照动.静来分). ①.静态分析测试法(编码前分析文档是否符合要求) ②.动态执行测试(通过运行程序来检验程序的动态行为和运行结果的正确性)Ⅱ(按

2018年四川理工学院软件工程考试大纲(软件维护)

2018年四川理工学院软件工程考试大纲(软件维护) 1.软件维护的分类 ①.改正性维护(是指软件运行的过程中,遇到了异常.故障进行的维护) ②.适应性维护(是指使软件适应不断变化的运行环境) ③.完善性维护(是指当用户对系统提出了新的功能与性能要求时,对软件进行的更新) ④.预防性维护(是指在满足用户当前需求时,提前考虑到下一步可能的需求) 2.非结构化维护.结构化维护 Ⅰ.非结构化维护(只有源程序,而文档很少或没有文档的软件,进行的维护) Ⅱ.结构化维护(用软件工程思想开发的各个阶段具有相应文

2018年四川理工学院软件工程考试大纲(面向对象的软件开发技术概述)

2018年四川理工学院软件工程考试大纲(面向对象的软件开发技术概述)   1.面向对象软件开发,需要建立哪三种模型 ①.对象模型(用于描述系统的数据结构,定义了系统"对谁做") ②.动态模型(定义了系统"何时做") ③.功能模型(定义了系统"做什么") 2.面向对象软件开发 对象是指生活中的具体事物,面向对象软件开发是指根据生活中具体的事物为基本单位所进行的软件开发 3.面向对象软件开发的过程 面向对象分析(OOA).面向对象设计(OOD).面向

2018年软考全年考试科目、时间安排

同学们,2018年软考考试时间及考试科目安排已出,上半年考试时间为5.26.--5.27.,期间假期很多,有效复习时间非常有限,现在可以开始复习了,有不明白的内容都可以给我留言.建议复习备考策略如下:第一阶段:考前60天之前,学习基础知识(上.下午考试课程)第二阶段:考前30天--60天,学习历年真题强化训练第三阶段:考前一个月,冲刺查缺补漏徐朋老师个人首页,海量视频随时学:http://edu.51cto.com/lecturer/7789394.html 原文地址:http://blog.5

2018.3 江苏省计算机等级考试 C语言 编程题答案

题目要求:给定一个数字范围,输出满足这些条件: 1.能被3整除: 2.包含数字5, 将满足的数字放在特定的数组里输出.输出这些数里5出现的个数.数字的个数. 想起来有点伤心,本来很简单的题,考试的时候程序写错一行,结果成了死循环,最后还没找出来错,下来以后才想起来.以后必须长点心. 代码: #include<stdio.h>int flag(int x0,int x1,int b[],int *p);int main(){int i,intnumber,fivenumber;//数字的个数.5

2018.6.19 Java模拟考试(基础习题)

Java模拟考试(基础习题) 一.单选题(每题1分 * 50 = 50分) 1.java程序的执行过程中用到一套JDK工具,其中javac.exe指( B ) A.java语言解释器 B.java字节码编译器 C.java文档生成器 D.java类分解器 2.在Java语言中,不允许使用指针体现出的Java特性是( D ) A.可移植 B.解释执行 C.健壮性 D.安全性 3. 00101010(&)00010111语句的执行结果是( C ) A.11111111 B.00111111 C.00

【2018.12.15】【考试总结】【模拟+逆序对+树状数组+贪心+multiset】爆零之旅

这是我悲惨的接近爆零的一次考试,但是本蒟蒻不能放弃,还是要总结的QAQ 答题卡 [题目背景] 八月是个悲惨的月份.先不谈炎热的天气,对于新生来说,八月意味着军训: 而对于高二高三的同学来说,八月意味着开学考试.而考试就意味着改卷,改卷 也就意味着答题卡.不幸的是,学校读答题卡的机器的评分软件坏了,wyx 就被 老师要求写一个评分的程序. [问题描述] 软件需要读入学生的姓名.试题答案以及学生的答题卡信息. 学生姓名 学校的信息管理系统中存储了所有学生的姓名,一共 名学生.每个学生的 名字的组成只

2019年春PAT甲级考试

这次考试不是很理想,一道题目没能做完. 自己原因差不多三条: 1.自己实力不够,准备时间也有点仓促,自己没能做到每道题目都有清晰的思路. 2.考试的心里素质不行,因为设备原因东奔西跑浪费了听过时间,自己心态有点不稳. 3.考场选择的太糟糕了,老师超级不负责任,设施也真的无语,电脑也无法复制测试用例,测试的时候必须要手动输入:老旧的机器,编译器只有2010年的vc和vs. 接下来自己要保持每天的练习,9月份换个考场再参加考试.今年的题目第四道反而不是很难,但是第三道题目条件比较多,因为中途更换机器

2018年6月PMP考试小结-计划和执行收获知识和证书

原文地址:http://blog.51cto.com/12925440/2150191