2023夏季(模拟考试)

目录

前言:

A-1 Trap

题目:

思路:

代码: 

A-2 Queue Using Two Stacks

题目:

思路:

代码: 

A-3 Rank of Binary Tree

题目:

思路:

代码: 

A-4 Big Number

题目:

思路:

代码: 


前言:

因为最近三年的题都不会在题库中出现,于是本人2023.11.25日斥巨资(49个钻石)买了2023年夏季的真题,简单模拟一下考试。

最后得了89分,最后一道题测试点2错误+最后两个测试点超时,用的方法也比较繁琐,所以改起来也不太好整,后来发现用multiset可能会简单一些。

整体来讲这张卷子并不是很难,但是第一题可能比较难模拟,所以通过率还没有第二和第三道题高,最后一道题确实有难度,但是还没到一个测试点都过不了的地步,结束后又看了一些AC大佬的题解,思路确实清晰。相关题目和题解已经放在下方。

A-1 Trap

题目:

A robot is designed to move on a map from South toward North. When some obstacle is encountered, the robot can only turn toward West and moves until it can turn toward North and continue.

Given a squared map with n×n blocks, a robot can start from any position below the bottom line (South) and its target is to reach the top line (North). (By the way, kindly remind you that the left-hand-side of the map is West and the right-hand-side is East.)

If some obstacles are placed in the map, the robot might get trapped if it starts from certain positions and can never reach the North line. For example, in the situation given by the following figure, the robot will be trapped if it starts from either position 7 or 8.

Your job is to point out those starting positions which will get the robot trapped.

Note: it is assumed that a robot can move out of the map boundary, and all the blocks around the map are open, without any obstacle. Hence if the robot starts from any position out of the West or East boundary, it can certainly reach North without any problem. Therefore we only have to consider the positions between the West and East boundaries (e.g. the positions from 1 to 10 below the South line in the above figure). Besides, as long as the robot can reach the North line, it is considered successful even of it ends up at out of the boundary (e.g. the robot will have to move out of the map if starts from either the positions 1 or 2, but it can still reach the North line).

Input Specification:
Each input file contains one test case. Each case starts from a positive integer n (≤100) in a line, which is the size of the map. Then n lines follow, each contains n characters, which are either 0 for an open block, or 1 for a block with obstacle. The first line corresponds to the North boundary and the last line the South.

Output Specification:
Output in a line all the starting positions which can get the robot trapped, in increasing order. The positions are indexed from West to East, starting from 1. It is guaranteed that there is at least one output.
All the numbers must be separated by 1 space, and there must be no extra space at the beginning or the end of the line.

Sample Input:

10
0000000000
0000111010
1100100011
0000110001
0000000011
0000000000
0100000100
0001000000
0001000000
0001100000

Sample Output:

7 8 

思路:

用二维数组模拟地图,然后能直走就直走,直走不了就左转,左转后进入死胡同就g。

代码: 

#include<bits/stdc++.h>
using namespace std;
int a[110][110], K;
int x, y;

int main()
{
	cin >> K;
	for(int j=K;j>=1;j--)
		for (int i = 1;i <= K;i++)
		{
			char c;cin >> c;
			a[j][i] = c - '0';
		}
	vector<int> v;
	for (int i = 1;i <= K;i++)
	{
		x = i, y = 0;
		int p = x, tag = 0;
		while (y <= K && x >= 0 && y >= 0)
		{
			while (a[y + 1][x] == 0 && y <= K)
				y++;
			if (x >= 1 && a[y + 1][x] == 1 && a[y][x - 1] == 0)
				x--;
			if (x >= 1 && a[y + 1][x] == 1 && a[y][x - 1] == 1){
					tag = 1;break;
				}
		}
		if (tag)
			v.push_back(p);
	}
	for (int i = 0;i < v.size();i++){
		if (i) cout << " ";
		cout << v[i];
	}
}

A-2 Queue Using Two Stacks

题目:

A queue (FIFO structure) can be implemented by two stacks (LIFO structure) in the following way:

  1. Start from two empty stacks s1​ and s2​.
  2. When element e is enqueued, it is actually pushed onto s1​.
  3. When we are supposed to dequeue, s2​ is checked first. If s2​ is empty, everything in s1​ will be transferred to s2​ by popping from s1​ and immediately pushing onto s2​. Then we just pop from s2​ – the top element of s2​ must be the first one to enter s1​ thus is the first element that was enqueued.

Assume that each operation of push or pop takes 1 unit of time. You job is to tell the time taken for each dequeue.

Input Specification:
Each input file contains one test case. For each case, the first line gives a positive integer N (≤103), which are the number of operations. Then N lines follow, each gives an operation in the format:

Operation Element

where Operation being I represents enqueue and O represents dequeue. For each I, Element is a positive integer that is no more than 106. No Element is given for O operations.
It is guaranteed that there is at least one O operation.

Output Specification:

For each dequeue operation, print in a line the dequeued element and the unites of time taken to do this dequeue. The numbers in a line must be separated by 1 space, and there must be no extra space at the beginning or the end of the line.
In case that the queue is empty when dequeue is called, output in a line ERROR instead.

Sample Input:

20 5
32 1
11 3
ERROR
100 5

思路:

模拟即可。

代码: 

#include<bits/stdc++.h>
using namespace std;
int N;
stack<int> a, b;

int main()
{
	cin >> N;
	char c;int v;
	while (N--)
	{
		cin >> c;
		if (c == 'I')
		{
			cin >> v;
			a.push(v);
		}
		else
		{
			int tag = 0;
			if (!a.size() && !b.size())
				cout << "ERROR" << endl;
			else if (a.size() && !b.size())
			{
				tag = a.size() * 2 + 1;
				while (a.size())
				{
					b.push(a.top());
					a.pop();
				}
				cout << b.top() << " " << tag << endl;
				b.pop();
			}
			else if (b.size())
			{
				cout << b.top() << " " << 1 << endl;
				b.pop();
			}
		}
	}
}

A-3 Rank of Binary Tree

题目:

Here we define the rank of a binary tree as n1​×n2​/n0​ where ni​ is the number of nodes of degree i for i=0,1,2.
For example, given a tree shown by the figure, its rank is 2×3/4=1.5.

fig.jpg

Given the inorder and preorder traversal sequences of a binary tree, you are supposed to calculate its rank.

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive integer N (≤20), which is the total number of nodes in the tree. Then given in the following 2 lines are the inorder and preorder traversal sequences of the tree, respectively. All the keys in the tree are distinct positive integers in the range of int.

Output Specification:

For each case, print in a line the way we calculate the rank, and the integer part of the rank. The format is:

n1 * n2 / n0 = rank

Sample Input:

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

Sample Output:

2 * 3 / 4 = 1

思路:

先建树,然后用dfs,题目中的degree指的是结点的度

代码: 

#include<bits/stdc++.h>
using namespace std;
int N, pre[21], in[21];
int r[3];

struct node {
	int l = -1, r = -1;
}v[1000000];

int build(int h1, int t1, int h2, int t2)
{
	if (h1 > t1) return -1;
	int root = pre[h1];
	int i;
	for (i = h2;root != in[i];i++);
	v[root].l = build(h1 + 1, i + h1 - h2, h2, i - 1);
	v[root].r = build(t1 + i + 1 - t2, t1, i + 1, t2);
	return root;
}

void dfs(int cur)
{
	if (cur == -1)
		return;
	if (v[cur].l != -1 && v[cur].r != -1)
		r[2]++;
	else if ((v[cur].l == -1 && v[cur].r != -1) || (v[cur].l != -1 && v[cur].r == -1))
		r[1]++;
	else if (v[cur].l == -1 && v[cur].r == -1)
		r[0]++;
	dfs(v[cur].l);
	dfs(v[cur].r);
}

int main()
{
	cin >> N;
	for (int i = 0;i < N;i++)
		cin >> in[i];
	for (int i = 0;i < N;i++)
		cin >> pre[i];
	int root = build(0, N - 1, 0, N - 1);
	dfs(root);
	cout << r[1] << " * " << r[2] << " / " << r[0] << " = " << r[1] * r[2] / r[0];
}

A-4 Big Number

题目:

How to generate a big number of N digits randomly? One way is to find N kids, give each one a card with one's index written on one side (hence it is assumed that the kids are indexed from 1 to N), and ask them to write down a 1-digit number randomly on the other side. Then let the kids pin their digits in a line, on the wall, one by one in ascending order of their indices.

However, it's very difficult to let hundreds of thousands of kids to follow the order. The result is that we have cards pinned randomly all over the wall, some even show the wrong sides. For example, if the 23rd kid has written down 8, we are supposed to find the number 8 on the wall. But instead we might find 23... Your job is to rearrange these cards so that we can obtain the big number as required.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (≤105). Then N lines follow, each describes a card in the format n1 n2 where the two numbers are the numbers written on the two sides of a card.

Output Specification:

For each test case, print in a line the N-digit number as required. That is, print the digits written by the kids in ascending order of their indices. In case that there are 1-digit numbers written on both sides, it would be hard to tell which one is the index and which one is the number written by the kid. Hence the solution may not be unique. In this case, just output the smallest resulting number.

It is guaranteed that a solution exists.

Sample Input:

12
7 11
8 9
3 1
2 12
4 6
10 0
5 1
2 5
6 8
1 4
7 2
9 3

Sample Output:

359114268072

思路:

这个最后只得了19分,有两个超时了,还有一个答案错误,做法可能比较繁琐了。

我最初的想法和PAT甲级2023夏季考试题解(100分)很一致,但是人家AC了。

我看了这个之后又发现了另一个题解,思路更加清晰,所以大家可以参考下面这个思路:

相关链接:PAT甲级_2023夏_满分思路-CSDN博客 

代码: 

AC代码:

#include<bits/stdc++.h>
using namespace std;
int n, a, b;
bool st[100100]; //对应于t 
vector<pair<pair<int, int>, int>> rec;//<<id, value>, t> 
vector<int> ans;
bool flag = false;
//以id顺序从1扫描到n,期望num最小,还需要记录卡片用过没有,所以用输入时间作为该卡片的另一属性,以避免重复使用 
void DFS(int ptr_id, int ptr_rec){
	//从rec数组从头到尾扫描,id是rec[i].first.first因为sort函数,所以也是升序排列的。
	//当前排列到第ptr_id个位置,扫描到ptr_rec,还没纳入需要 
	if(flag) return;
	if(ptr_id == n + 1){
		for(int i = 0; i < ans.size(); i ++) printf("%d", ans[i]);
		flag = true;
		return;
	}
	for(int i = ptr_rec; i < rec.size(); i ++){
		if(rec[i].first.first < ptr_id) continue;
		if(rec[i].first.first > ptr_id) break;
		if(st[rec[i].second]) continue;//用过了 
		st[rec[i].second] = true;
		ans.push_back(rec[i].first.second);
		DFS(ptr_id + 1, i + 1);
	}
}
int main(){
	scanf("%d", &n);
	for(int i = 1; i <= n; i ++){
		scanf("%d %d", &a, &b);
		rec.push_back({{a, b}, i});
		rec.push_back({{b, a}, i});
	}
	sort(rec.begin(), rec.end());
	DFS(1, 0);
	return 0;
}

附上一个我的19分代码:

#include<bits/stdc++.h>
using namespace std;
int N;
int r[100010];
map<int, vector <pair<int, bool>> > p;

bool comp(pair<int, bool> p1, pair<int, bool> p2)
{
	return p1.first < p2.first;
}

int main()
{
	cin >> N;
	int a, b;
	for (int i = 0;i <= N;i++)
		r[i] = -1;
	for (int i = 0;i < N;i++)
	{
		cin >> a >> b;
		p[a].push_back(make_pair(b, 0));
		p[b].push_back(make_pair(a, 0));
	}
	for (int i = 1;i <= N;i++)
		sort(p[i].begin(), p[i].end(), comp);
	for (int i = 1;i <= N;i++)
	{
		if (r[i] == -1)
		{
			for (int j = 0;j < p[i].size();j++)
			{
				if (p[i][j].second != 1)
				{
					int tag = 0;
					for (int h = 0;h <= p[p[i][j].first].size();h++)
					{
						if (p[p[i][j].first][h].second == 1)
							tag++;
					}
					if (p[p[i][j].first].size() - tag >= 2 || p[i][j].first == 0 || p[i][j].first>N)
					{
						r[i] = p[i][j].first;
						for (int k = 0;k < p[p[i][j].first].size();k++)
						{
							if (p[p[i][j].first][k].first == i && p[p[i][j].first][k].second == 0)
							{
								p[p[i][j].first][k].second = 1;
								break;
							}
						}
						break;
					}
				}
				else {
					r[p[i][j].first] = i;
				}
			}
		}
	}
	for (int i = 1;i <= N;i++)
		cout << r[i];
}
  • 22
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值