PAT甲级_2021冬(AK)

总结

第六次模考,第1、3题简单。第二题因为阅读理解卡了30min,最后一题因为边界判断问题debug1h。最后AK时只剩10min。英语有待加强,floyd还需巩固。
在这里插入图片描述

第一题

22min

题意

给定n个站点和m个事件。然后依次m行分别给出各站点的观点,通过不同数字表示不同观点。
对同一个事件,分别计算和每一个站点持不同观点的站点数。最大值对应的站点被视为发布了fake news。
输出发布最多fake news数的站点。题目保证只有一个输出。
news site: 新闻站点
intentionally and verifiably:故意的且可验证的。

思路

通过unordered_map cnt记录某观点出现的次数。
通过int min_com记录相同观点数的最小值。
通过int ans[100010]记录fake news的数量。

  • 得到n、m。循环m次。
    • 每次接收n家新闻站点的信息,同时记录该观点出现的次数。
    • 遍历所有出现的观点,找到观点出现的最小次数记为min_com,这个次数就是fakenews出现的次数。
    • 对所有出现次数为min_com的site对应的ans数组进行++操作。
  • 遍历ans数组,最大值对应下标+1就是site的编号。

小结

这里由于没看懂site的意思,琢磨题意很长时间。

题解

#include<bits/stdc++.h>
using namespace std;
int n, m;
int a[101][10001];
int cnt_n[20001], ans[10001];
int main(){
	cin>>n>>m;
	for(int i = 0; i < m; i ++){
		memset(cnt_n, 0, sizeof cnt_n);
		for(int j = 0; j < n; j ++){
			scanf("%d", &a[i][j]);
			a[i][j] += 10000; 
			cnt_n[a[i][j]]++;
			
		}
		int max_n = -1;
		for(int j = 0; j < n; j ++)
			if(max_n == -1 || cnt_n[a[i][j]] < cnt_n[a[i][max_n]]) max_n = j;
		for(int j = 0; j < n; j ++)
			if(cnt_n[a[i][max_n]] == cnt_n[a[i][j]]) ans[j]++;
	} 
	int ptr = -1;
	for(int i = 0; i < n; i ++)
		if(ptr == -1 || ans[ptr] < ans[i]) ptr = i;
	cout<<ptr + 1<<endl;
	return 0;
}

题解 - 优化待测试

#include<bits/stdc++.h>
using namespace std;
int n, m, a[10001], ans[10001];
int main(){
	cin>>n>>m;
	for(int i = 0; i < m; i ++){
		unordered_map<int, int>cnt;
		for(int j = 0; j < n; j ++){
			scanf("%d", &a[j]);
			cnt[a[j]]++;
		}
		int min_com = n;
		for(auto j : cnt)
			min_com = min(min_com, j);
		for(int j = 0; j < n; j ++)
			if(cnt[a[j]] == min_com) ans[j]++;	
	}
	int ptr = 0;
	for(int i = 0; i < n; i ++)
		if(ans[ptr] < ans[i]) ptr = i;
	cout<<ptr + 1<<endl;
	return 0;
}

第二题

45min

题意

有一个链表,addr为数组下标,next指针为数组元素。对链表从头到尾进行编号1 - n作为结点data。然后按照数组顺序输出编号。

思路

  • 找到数组的终点rear。if(a[i] == -1) rear = i;
  • 建立反向指针pre记在front数组中。if(a[i] != -1) front[a[i]] = i;
  • 从队尾rear遍历得到ans数组,即链表,内容存的addr。
  • 对addr进行排名ran[ans[i]] = cnt++;
  • 输出rank数组即可。

小结

开始题目理解错了,以为是输出数组元素在链表中的位置。实际是对元素排名,链表头部所在下标排名为1,以此类推。

题解

#include<bits/stdc++.h>
using namespace std;
int n, rear, a[100010], front[100010], ran[100010];
bool st[100010];
int main(){
	cin>>n;
	for(int i = 0; i < n; i ++){
		scanf("%d", &a[i]);
		if(a[i] != -1)front[a[i]] = i;
		else if(a[i] == -1) rear = i;
	}
	deque<int> ans;
	while(ans.size() != n){
		ans.push_front(rear);//从链表头部到尾部addr
		rear = front[rear];
	}
	int cnt = 1;
	for(int i = 0; i < n; i ++)
		ran[ans[i]] = cnt++; // ans[i]是链表第i个元素,令其下标位置
	for(int i = 0; i < n; i ++){
		if(i)printf(" ");
		printf("%d", ran[i]);
	}
	return 0;
}

错解

#include<bits/stdc++.h>
using namespace std;
int n, rear, a[100010], front[100010];
bool st[100010];
int main(){
	cin>>n;
	for(int i = 0; i < n; i ++){
		scanf("%d", &a[i]);
		if(a[i] != -1)front[a[i]] = i;
		else if(a[i] == -1) rear = i;
	}
	deque<int> ans;
	while(ans.size() != n){
		ans.push_front(rear + 1);//从链表头部到尾部addr+1
		rear = front[rear];
	}
	for(int i = 0; i < n; i ++){
		if(i)printf(" ");
		printf("%d", ans[i]);
	}
	return 0;
}

第三题

10min

题意

给出结点数n,这n个结点构成一颗树。然后询问k次,每次给出一个节点编号,要求输出以该结点为根的子树的节点个数。规定第一个元素是根。

思路

简单DFS,从将军向下遍历,每次DFS返回节点数,退出是即可知道该结点对应子树结点个数。

题解

#include<bits/stdc++.h>
using namespace std;
int n, m, q, a[100010], cnt[100010], p[100010];
vector<vector<int>> rec;
int DFS(int s, int num){
	for(auto i : rec[s])
		num += DFS(i, 0);
	num++;
	cnt[s] = num;
	return num;
}
int main(){
	cin>>n;
	rec.resize(n + 1);
	for(int i = 2; i <= n; i ++){
		cin>>a[i];
		rec[a[i]].push_back(i);
	}
	DFS(1, 0);
	cin>>m;
	while(m--){
		cin>>q;
		cout<<cnt[q]<<endl;
	}
	return 0;
}

第四题

90min

题意

首先给出要送出的n个包裹的信息(ddl时间,送到赚多少y,超时发多少p),然后给出n个包裹和运输中心之间的m条路径。然后给出k种可能,每种可能长度为n,询问这k种方法中哪条最赚钱,同时最赚钱的路径哪条最快完成。按要求输出。

思路

  • 先用node rec[1001]记录每个包裹的信息。
  • 然后用int f[1001][1001]记录路径。
  • 通过Floyd算出最终f数组。
  • 然后对k条路径进行检查,由于一定有一个解,所以不会存在包裹间不可达的情况,只用判断给出的n个值有没有重复,如果重复则跳过。
  • 根据每条路径算出的结果进行比较,按要求输出较优解。
  • 注意:
    • 最终可能得到的路径都是要赔钱的,p可能大于y。
    • 送达时间可能超出24小时,最后要模1440。

小结

  • 对floyd不熟悉,王道的代码健壮性不够,比如有重边的时候,需要取较小值更新。同时对于不可达的边建议改为0x3f3f3f3f。然后floyd思想是动态规划,所以一定是一步步改的。
  • 注意边界,当p大于y,所有路径都赔钱时,需要使比较值的初始为-1E9。当时间t过大超过24小时时,要mod1440。这里debug了快1h。

题解

#include<bits/stdc++.h>
using namespace std;
int n, m, hh, mm, ddl, y, p, v1, v2, l, t, k;
deque<int> road;
int f[1001][1001];
bool exi[1001];
struct node{
	int hh, mm, t, y, p;
}rec[1001];
int main(){
	scanf("%d %d %d:%d", &n, &m, &hh, &mm);
	t = hh * 60 + mm;
	memset(f, 0x3f, sizeof f);
	for(int i = 1; i <= n; i ++){
		scanf("%d:%d %d %d", &rec[i].hh, &rec[i].mm, &rec[i].y, &rec[i].p);
		rec[i].t = rec[i].hh * 60 + rec[i].mm;
	}
	for(int i = 0; i <= n; i ++) f[i][i] = 0;
	for(int i = 1; i <= m; i ++){
		scanf("%d %d %d", &v1, &v2, &l);
		f[v1][v2] = min(f[v1][v2], l);
		f[v2][v1] = min(f[v2][v1], l);
	}
	for(int k = 0; k <= n; k ++)
		for(int i = 0; i <= n; i ++)
			for(int j = 0; j <= n; j ++){
				if(i == j || !f[i][k] || !f[k][j]) continue;
				f[i][j] = min(f[i][j], f[i][k] + f[k][j]);
				f[i][j] = min(f[i][j], f[i][k] + f[k][j]);	
			}
	cin>>k;
	int ans_money = -INT_MAX, min_t = INT_MAX;
	while(k--){
		road.resize(n);
		bool flag = true;
		memset(exi, false, sizeof exi);
		for(int i = 0; i < n; i ++){
			scanf("%d", &road[i]);
			exi[road[i]] = true;
		}
		for(int i = 1; i <= n; i ++){
			if(exi[i] == false){
				flag = false;
				break;
			}
		}
		if(!flag) continue;
		road.push_back(0);
		int s = 0, st = t, money = 0;
		while(road.size()){
			int e = road.front();
			exi[e] = true;
			road.pop_front();
			st+= f[s][e];
			//if(st > 1440) flag = false;
			if(st > rec[e].t) money -= rec[e].p;
			money += rec[e].y;
			s = e;
		}
		if(!flag)continue;
		if(money > ans_money)
			ans_money = money, min_t = st;
		else if(money == ans_money)
			min_t = min(min_t, st);
	}
	min_t %= 1440;
	printf("%d %02d:%02d",ans_money, min_t / 60 , min_t % 60);
	return 0;
}

7-1 Fake News

No news site is unbiased, but some do a better job of trying to balance facts and opinions. The term fake news means “news articles that are intentionally and verifiably false” designed to manipulate people’s perceptions of real facts, events, and statements. (Quoted from https://www.cits.ucsb.edu/fake-news/what-is-fake-news)

To tell if a news media is more or less likely to be fake, you can keep an eye on several different sites to see how they report on the same important events. The algorithm works as the following:

  • Select N news sites.
  • For each important event, scan every site and represent each different opinion by a distinct integer.
  • Define the likelihood of a site i being fake news by Fi​=ni​/N, where ni​ is the number of sites that have different opinions than site i.
  • Find the news site(s) which is(are) the most likely to report fake news.
  • For each news site, count the number of times it was the most likely to be fake, and find the one that is in most of the cases the most likely to be fake.

Input Specification:

Each input file contains one test case. For each case, the first line contains two positive numbers: N (≤104) which is the number of news sites, and M (≤100) which is the number of events. Then M lines follow, each describes the reports of the sites in the format:

R1​ R2​ … RN​

where Ri​ is an integer in the range [−104,104], and reprensts the opinion of site i.

Output Specification:

For each test case, print in a line the index of the site which is in most of the cases the most likely to be fake. The answer is guaranteed to be unique.

Sample Input:

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

Sample Output:

4

Hint:

The Fi​’s for each event are the following:

Event 1: 3/4 3/4 2/4 2/4 --> 1 and 2 are the most likely
Event 2: 1/4 1/4 1/4 3/4 --> 4 is the most likely
Event 3: 3/4 2/4 2/4 3/4 --> 1 and 4 are the most likely
Event 4: 0 0 0 0 --> all are the most likely
Event 5: 2/4 2/4 2/4 2/4 --> all are the most likely
Event 6: 2/4 2/4 3/4 3/4 --> 3 and 4 are the most likely

Hence site 4 is the one since it has the highest likelihood for 5 times, while other sites only have 3 or 4 times.

7-2 Rank a Linked List

A linked list of n nodes is stored in an array of n elements. Each element contains an integer data and a next pointer which is the array index of the next node. It is guaranteed that the given list is linear – that is, every node, except the first one, has a unique previous node; and every node, except the last one, has a unique next node.

Now let’s number these nodes in order, starting from the first node, by numbers from 1 to n. These numbers are called the ranks of the nodes. Your job is to list their ranks.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive number n (≤105) which is the total number of nodes in the linked list. Then n numbers follow in the next line. The ith number (i=0,⋯,n−1) corresponds to next(i) of the ith element. The NULL pointer is represented by −1. The numbers in a line are separated by spaces.

Output Specification:

List n ranks in a line, where the ith number (i=0,⋯,n−1) corresponds to rank(i) of the ith element. The adjacent numbers in a line must be separated by exactly 1 space, and there must be no extra space at the beginning or the end of the line.

Sample Input:

5
3 -1 4 1 0

Sample Output:

3 5 1 4 2

Hint:

The given linked list is stored as 2->4->0->3->1->NULL. Hence the 0th element is ranked 3 since it is the 3rd node in the list; the 1st element is ranked 5 since it is the last (the 5th) node in the list; and so on so forth.

7-3 Size of Military Unit

army.jpg

The Army is a large organization, made up of many different branches and groups. Each group is called a “unit”. The Army has a hierarchical structure (等级结构) – that is, each senior officer gives commands to many units, and the commander of a unit reports to the only senior officer who gives commands directly to him/her. There is a unique General of the Armies who holds the highest rank.

Now given the list of soldiers and their senior officers, your job is to tell the size (number of soldiers) of any specific unit.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (2≤N≤105), which is the total number of soldiers in the army. Assume all the soldiers are numbered from 1 to N, and General of the Armies is always the number 1. Then the next line gives N−1 numbers, each corresponds to an officer or a soldier numbered from 2 to N. The ith number corresponds the only senior officer who gives commands directly to the ith soldier. Notice that since General of the Armies holds the highest rank and is the number 1, the above list starts from the 2nd officer/soldier.

Then a positive integer M (≤N), the number of queries, is given in a line. Followed in the next line are M numbers, each represents a soldier.

Output Specification:

For each soldier in a query, output in a line the size of his/her unit.

Sample Input (the structure is shown by the figure below):

10
4 6 6 8 1 8 1 8 8
4
8 6 4 9

sample.JPG

Sample Output:

5
4
2
1

7-4 Helping the Couriers

Gao recently took a part time job as a courier(快递员). Every time as he picks up N packages from the distribution center, he would always try to find the best way to deliver those packages so that he can finish this round as quickly as possible. On the other hand, as a programmer, Gao understands that finding the simple cycle that visits all the vertices with the minimum time is an NP hard problem. So he wouldn’t ask you to find the best solution for him. Instead, he would give you several plans to check, and you are supposed to tell him the best plan.

What makes this job a little bit complicated is that every package has a deadline for delivery. If Gao can deliver the package in time, he will receive Y yuans payment; or if he misses the deadline, he will be penalized and lose P yuans after gaining Y yuans payment. He would choose the plan that can gain him the most amount of payment first. If there are more than one choices, he would pick the one with the minimum total time of delivery.

It is assumed that Gao would always choose the shortest path between any pair of destinations, but he will NOT deliver any package on the way along the shortest path.

Input Specification:

Each input file contains one test case. For each case, the first line gives two positive numbers and a time: N (≤103) which is the total number of packages, M, the number of streets among those delivery points, and the starting time of the delivery tour, in the format hh:mm where hh is the hour and mm is the minute, and the time is in the range from 08:00 to 17:00. Here we assume that the package delivery points are numbered from 1 to N and the distribution center is numbered 0.

Then N lines follow. The ith line gives the information of the ith package, in the format

deadline Y P

where deadline is the deadline for delivery and is also in hh:mm. It is assumed that all the deadlines are in [00:00, 23:59] within the same day of the starting time; Y is the payment for successfully delivering this package no later than the deadline; and P is the penalty for missing the deadline, both are no more than 104.

And then M lines follow, each describes a street in the format

V1 V2 time

where V1 and V2 are the indices of the two ends of this street, and time is the minutes (≤120) taken to pass this street. It is guaranteed that Gao can reach every delivery point, either directly or indirectly.

Finally there is a positive integer K (≤100) followed by K lines of plans, each contains N indices corresponding to an order of delivery. It is assumed that Gao always starts from 0 and returns to 0, hence 0 is not explicitly given in the input plan. The numbers in a line are separated by spaces.

Output Specification:

Among all the given plans, find the plan with the maximum payment that Gao can gain and the minimum time taken for him to complete this round of delivery. Print in a line the payment and the time he gets back to the distribution center (in the format hh:mm). The numbers must be separated by exactly 1 space and there must be no extra space at the beginning or the end of the line.

By the way, you must ignore those plans that are impossible for Gao to finish his job. On the other hand, it is guaranteed that there is at least one plan that is feasible.

Sample Input:

5 11 08:00
09:00 10 2
08:30 50 10
13:00 5 1
08:35 20 3
08:30 200 80
1 0 5
0 2 30
3 0 20
0 4 40
4 5 5
1 4 21
1 3 60
1 2 30
2 3 10
3 4 2
2 4 60
5
1 4 5 3 2
3 4 5 2 1
3 4 5 1 2
5 1 2 3 1
5 4 1 3 2

Sample Output:

275 09:53

Hint:

Plan 4 is obviously impossible since point 4 is not in. The arriving times and payments for other plans are show in the following table. Plan 3 and 5 both give the maximum payments, yet Plan 3 takes fewer time. Hence the answer is Plan 3 with payment 275 and completion time 09:53.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值