写在开头的话: 甲级考试多是考查数据结构和一些基础的算法,此次也是我第一次参加PAT考试,赛前约刷了90道题(一个月),得到了一个80分以上的成绩,自我感觉得到了一下几方面的提升:
题解如下:
Werewolf(狼人杀) is a game in which the players are partitioned into two parties: the werewolves and the human beings. Suppose that in a game,
Given that there were 2 werewolves among them, at least one but not all the werewolves were lying, and there were exactly 2 liers. Can you point out the werewolves?
Now you are asked to solve a harder version of this problem: given that there were Nplayers, with 2 werewolves among them, at least one but not all the werewolves were lying, and there were exactly 2 liers. You are supposed to point out the werewolves.
Each input file contains one test case. For each case, the first line gives a positive integer N(5≤N≤100). Then N lines follow and the i-th line gives the statement of the i-th player (1≤i≤N), which is represented by the index of the player with a positive sign for a human and a negative sign for a werewolf.
If a solution exists, print in a line in ascending order the indices of the two werewolves. The numbers must be separated by exactly one space with no extra spaces at the beginning or the end of the line. If there are more than one solution, you must output the smallest solution sequence – that is, for two sequences A=a[1],…,a[M] and B=b[1],…,b[M], if there exists 0≤k
5
-2
+3
-4
+5
+4
1 4
6
+6
+3
+1
-5
-2
+4
1 5
5
-2
-3
-4
-5
-1
No Solution
题意: N个玩家玩狼人杀,每个人都会说一个人是好人或者是狼,正数表示好人、负数表示狼,其中必须要注意“Given that there were 2 werewolves among them, at least one but not all the werewolves were lying, and there were exactly 2 liers. ”,这句话的意思是:必有一人和一狼说假话。考试时理解为至少有一狼说谎,因此第一个样例(6分)过不了,所以考甲级之前英语的过关啊。
分析: 由于数据规模N<=100,果断就3重循环暴力求解了。第一二层循环枚举狼,第三层循环验证N个人说的话是否满足一人一狼说谎的要求。
代码如下:
#include
#include
using namespace std;
int a[105] = { 0 };
int main()
{
int n;
cin >> n;
for (int i = 1; i <= n; i++)cin >> a[i];
int f1, f2; // f1记录狼说谎的个数,f2记录民说谎的个数
for (int i = 1; i 0)f1++;
}
else
{
if (a[k] < 0)f1++;
}
}
else // 若是人,计算说谎次数
{
if (dir == i || dir == j)
{
if (a[k] > 0)f2++;
}
else
{
if (a[k] < 0)f2++;
}
}
}
if (f2 == 1 && f1 == 1) // 关键点
{
cout << i << " " << j;
return 0;
}
}
}
cout << "No Solution";
return 0;
}
When shipping goods with containers, we have to be careful not to pack some incompatible goods into the same container, or we might get ourselves in serious trouble. For example, oxidizing agent (氧化剂) must not be packed with flammable liquid (易燃液体), or it can cause explosion.
Now you are given a long list of incompatible goods, and several lists of goods to be shipped. You are supposed to tell if all the goods in a list can be packed into the same container.
Each input file contains one test case. For each case, the first line gives two positive integers: N (≤104), the number of pairs of incompatible goods, and M (≤100), the number of lists of goods to be shipped.
Then two blocks follow. The first block contains N pairs of incompatible goods, each pair occupies a line; and the second one contains M lists of goods to be shipped, each list occupies a line in the following format:
K G[1] G[2] ... G[K]
where K
(≤1,000) is the number of goods and G[i]
's are the IDs of the goods. To make it simple, each good is represented by a 5-digit ID number. All the numbers in a line are separated by spaces.
For each shipping list, print in a line Yes
if there are no incompatible goods in the list, or No
if not.
6 3
20001 20002
20003 20004
20005 20006
20003 20001
20005 20004
20004 20006
4 00001 20004 00002 20003
5 98823 20002 20003 20006 10010
3 12345 67890 23333
No
Yes
Yes
题意: 给出多对不能放在一起的物品,现有多个查询,判断所查询的一堆物品是否能否在一起,能-Yes、否-No。
分析: 第一眼以为是并查集,因为PAT确实考得多,结果写着写着发现不是,就一水题,直接上代码。
#include
#include
The “travelling salesman problem” asks the following question: “Given a list of cities and the distances between each pair of cities, what is the shortest possible route that visits each city and returns to the origin city?” It is an NP-hard problem in combinatorial optimization, important in operations research and theoretical computer science. (Quoted from “https://en.wikipedia.org/wiki/Travelling_salesman_problem”.)
In this problem, you are supposed to find, from a given list of cycles, the one that is the closest to the solution of a travelling salesman problem.
Each input file contains one test case. For each case, the first line contains 2 positive integers N (2Dist
is positive and is no more than 100. The next line gives a positive integer K which is the number of paths, followed by K lines of paths, each in the format:
n C1 C2 … Cn
where n is the number of cities in the list, and Ci’s are the cities on a path.
For each path, print in a line Path X: TotalDist (Description)
where X
is the index (starting from 1) of that path, TotalDist
its total distance (if this distance does not exist, output NA
instead), and Description
is one of the following:
TS simple cycle
if it is a simple cycle that visits every city;TS cycle
if it is a cycle that visits every city, but not a simple cycle;Not a TS cycle
if it is NOT a cycle that visits every city.Finally print in a line Shortest Dist(X) = TotalDist
where X
is the index of the cycle that is the closest to the solution of a travelling salesman problem, and TotalDist
is its total distance. It is guaranteed that such a solution is unique.
6 10
6 2 1
3 4 1
1 5 1
2 5 1
3 1 8
4 1 6
1 6 1
6 3 1
1 2 1
4 5 1
7
7 5 1 4 3 6 2 5
7 6 1 3 4 5 2 6
6 5 1 4 3 6 2
9 6 2 1 6 3 4 5 2 6
4 1 2 5 1
7 6 1 2 5 4 3 1
7 6 3 2 5 4 1 6
Path 1: 11 (TS simple cycle)
Path 2: 13 (TS simple cycle)
Path 3: 10 (Not a TS cycle)
Path 4: 8 (TS cycle)
Path 5: 3 (Not a TS cycle)
Path 6: 13 (Not a TS cycle)
Path 7: NA (Not a TS cycle)
Shortest Dist(4) = 8
题意: 输入一幅图,给你路径,需要判断路径是否访问了所有城市并回到原点(形成环)。并给出三种判别:
分析: 此题是一个高起点低落点的题,主要是一个写判断条件的题,分清三种判别需要满足什么条件。
现给出四个条件,路径是否存在f1、是否成环f2、是否是最简单f3、是否每个城市都访问过f4。
1、f1或f2或f4不满足都属于–Not a TS cycle
2、满足f1、f2、f4–TS cycle
3、满足全部–TS simple cycle
#include
#include
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.
Given any two nodes in a binary tree, you are supposed to find their LCA.
Each input file contains one test case. For each case, the first line gives two positive integers: M (≤ 1,000), the number of pairs of nodes to be tested; and N (≤ 10,000), the number of keys in the binary tree, respectively. In each of the following two lines, N distinct integers are given as the inorder and preorder traversal sequences of the binary tree, respectively. It is guaranteed that the binary tree can be uniquely determined by the input sequences. Then M lines follow, each contains a pair of integer keys U and V. All the keys are in the range of int.
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 binary tree, print in a line ERROR: U is not found.
or ERROR: V is not found.
or ERROR: U and V are not found.
.
6 8
7 2 3 4 6 5 1 8
5 3 7 2 6 4 8 1
2 6
8 1
7 9
12 -3
0 8
99 99
LCA of 2 and 6 is 3.
8 is an ancestor of 1.
ERROR: 9 is not found.
ERROR: 12 and -3 are not found.
ERROR: 0 is not found.
ERROR: 99 and 99 are not found.
题意: 给你中序、前序遍历,问你任意两个节点,判断他们最矮的父节点。
分析: 刷过PintiA的同学们最喜欢的见到的之一就是利用前序、中序建树,注意此题由于测试规模过大,只能用下标建树,否则会MLE。然后就是找两节点的最矮父节点,用DFS可找到树中任意结点,但是也不能用一个vector记录路径否则也会MLE。故要想办法,如何直接抛出LCA结点。本题还需要记录所有出现过的值,用map即可。
代码如下:
#include
#include
#include
#include
总结:做题解的时候发现还是挺轻松的,也感叹这一个月训练确实学习了很多,个人觉得对于数据结构和算法,要想深刻理解必须去敲。由于第一次考PAT还是有些许紧张,感觉发挥不好,第一题理解错题意,第四题卡了3个MLE,但总体来讲难度适中,和练习题差不多,希望下次参加的时候能拿满分吧。