其他分享
首页 > 其他分享> > 劝退专业第一次PAT甲级(2020年冬季)考试经验

劝退专业第一次PAT甲级(2020年冬季)考试经验

作者:互联网

劝退专业第一次PAT甲级(2020年冬季)考试经验

自我介绍

生化环材一员,刚读研究生就发现自己不适合科研,2019年10月开始学习Python,疫情在家开始学习数据结构和算法,一开始全部都不懂,链表都是自己在b站看了好多视频才看懂,后来一次偶然的机会,找背包问题的视频的时候看到了y总的背包九讲,于是了解了acwing,往后,一直在acwing学习,开始学着用C++去写算法题,C++写算法题速度比较快,因此后面才学着写C++,2020年冬季第一次参与甲级考试,考试成绩93分,第一次考试我还是相对满意的。

第一题 The Closest Fibonacci Number

在这里插入图片描述
第一题很简单,看到题目后基本就知道怎么做,题目的意思是给一个数给你,让你找斐波那契数列中和这个数字最相近的数字,如果有两个数一样相近,则输出一个比较小的数字。这个题目直接写出斐波那契数列就好了。

#include <iostream>
#include <cstring>
#include <vector>

using namespace std;

int n;
vector<int> map;

int main()
{
	cin >> n;
	
	map.push_back(0); // 给数组中赋初始值
	map.push_back(1);
	
	while ( map[map.size() - 1] < n) // 当数组中的最后一个数都比给定数字小的话,就继续往数组中加数组
	{
		int u = map.size() - 1;
		map.push_back(map[u] + map[u - 1]);
	}
	
	int u = map.size() - 1;
	if ( abs(map[u - 1] - n) <= abs(map[u] - n)) cout << map[u - 1] << endl;
	else cout << map[u] << endl;
	
	return 0;
}

第二题 Subsequence in Substring

在这里插入图片描述

第二题也是比较简单的题目,题目的意思是给两个字符串,第一个是模板字符串(A),第二个是要找的字符串(B),你需要输出最短的包括字符串B的子串。这个题目一开始我以为要用KMP算法,内心还慌了一下,以为用暴力搜索肯定会超时,结果发现并没有。最后考试的时候就是用了两个指针去循环。

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

string a, b;

int main()
{
	cin >> a >> b;
	
	string res;
	if ( a == b) // 特殊判断,有个测试点,1分
	{
		cout << a << endl;
		return 0;
	}
	for ( int i = 0; i < a.size() - b.size(); i ++) //定义两个指针
	{
		int j = 0;
		if ( a[i] != b[j]) continue; // 如果第一个初始字符都不符合,则下一个循环
		else
		{
			int k = i; // 第一个字符符合
			while ( k < a.size() && j < b.size())
			{
				if ( a[k] == b[j]) // 如果k, j字符相同,两者均往后走
				{
					k ++;
					j ++;
				}
				else k ++; // 如果字符不相同,则只有k指针往后走
			}
			if ( j == b.size() && ( res == "" || res.size() > k - i)) // 如果j指针能够走到最后,说明在这个子串中能够全部包括B字符串,比较res大小,选择更新res
			{
				//cout << i << ' ' << k << endl;
				res = a.substr(i, k - i);
			}
		}
	}
	cout << res << endl;
	
	return 0;
}

第三题 File Path

在这里插入图片描述
第三题是一个多叉树的题目,一开始看到题目没看太懂,题目给的example都没搞清楚,只知道前面的空格数量代表这个文件在多叉树中的深度,一开始就定义了两个哈希表,将文件和深度全部存进了哈希表,找答案的时候就从深度为0到答案文件的深度,但是每个深度的文件其实很多,这个是我没太理解题意的地方。后来发现,文件的根应该是往上找到的第一个深度减一的文件,问题也就迎刃而解了。

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <unordered_map>

using namespace std;

int n, m;
unordered_map<string, int> map;
unordered_map<int, vector<string>> next, hah;
unordered_map<string, int> pos;
string in[1010];

int main()
{
	cin >> n;
	getchar();
	
	for ( int i = 0; i < n; i ++)
	{
		string line;
		getline(cin, line);
		
		int j = 0;
		while ( line[j] == ' ') j ++; // 找到该文件的深度
		
		map[line.substr(j)] = j; // 哈希映射,每个文件对应自己的深度
		hah[j].push_back(line.substr(j));
		in[i] = line.substr(j); // 顺序记录文件
		pos[line.substr(j)] = i; // 记录文件在顺序文件中的下标
	}
	
	cin >> m;
	for ( int i = 0; i < m; i ++)
	{
		string id;
		cin >> id;
		
		if ( !map.count(id)) printf("Error: %s is not found.\n", id.c_str());
		else
		{
			int k = pos[id];
			vector<string> path;
			int depth = map[id]; // 找到深度,开始往上找
			for  ( int j = k; j >= 0; j --)
			{
				if ( map[in[j]] == depth) // 在往上找的过程中,如果出现某个文件和当前的depth相符合,depth--,继续往上找
				{
					path.push_back(in[j]); // 找到的文件放到答案数组中
					depth --;
				}
			}
			
			for ( int i = path.size() - 1; i >= 0; i --)
			{
				if ( i == path.size() - 1) printf("%s", path[i].c_str());
				else printf("->%s", path[i].c_str());
			}
			puts("");
		}
	}
	
	return 0;
}

第四题 Chemical Equation

在这里插入图片描述
第四题我考试看到的时候简直要裂开了,作为一个材料专业的学生,在考编程考试的时候还能看到化学方程式,简直当场裂开,而且题目这么长,简直搞心态。题目的意思是给你一系列的化学方程式,然后给你一些反应物,一些产物,让你写出从反应物得到产物的化学方程式。这个题目我就不分析了(自己也少拿了7分,没有完全搞清楚),拿到题目的时候都不知道这个题目到底考什么算法,但是好在自己写的也混了一部分分数。

#include <iostream>
#include <cstring>
#include <algorithm>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

int n, m, k;
int rectant[25];
int rec_or[25];
int product[55];
unordered_map<int, vector<vector<int>>> map;
unordered_set<int> has;

bool dfs(vector<int> u)
{
	bool res = true;
	for ( int i = 0; i < u.size(); i ++)
	{
		if ( has.count(u[i])) continue;
		else
		{
			if ( !map.count(u[i])) res = false;
			else
			{
				bool flag = false;
				for ( auto ut: map[u[i]])
				{
					if ( dfs(ut))
					{
						flag = true;
						break;
					}
				}
				if ( !flag)
				{
					res = false;
					break;
				}
			}
		}
	}
	return res;
}

void get(int x, vector<int>& rect)
{
	if ( has.count(x))
	{
		rect.push_back(x);
		return;
	}
	else
	{
		auto u = map[x];
		for ( auto ut: u)
		{
			if (dfs(ut))
			{
				for ( auto utt: ut) get(utt, rect);
			}
		}
	}
}

int main()
{
	cin >> n;
	for ( int i = 0; i < n; i ++)
	{
		cin >> rectant[i];
		//rec_or[i] = rectant[i];
		has.insert(rectant[i]);
	}
	
	sort(rectant, rectant + n);
	
	cin >> m;
	for ( int i = 0; i < m; i ++) cin >> product[i];
	
	cin >> k;
	getchar();
	while ( k --)
	{
		string line;
		getline(cin, line);
		vector<int> rec;
		int pro;
		
		int i = 0;
		while ( true)
		{
			int j = i;
			while ( j < line.size() && line[j] >= '0' && line[j] <= '9') j ++;
			
			rec.push_back(stoi(line.substr(i, j - i)));
			i = j;
			
			while (!(line[i] >= '0' && line[i] <= '9') && line[i] != '-') i ++;
			//cout << i << endl;
			if ( line[i] == '-') break;
		}
		
		int j = line.size() - 1;
		pro = stoi(line.substr(j - 2));
		
		//for ( auto re: rec) cout << re << ' ';
		//cout << pro << endl;;	
		
		map[pro].push_back(rec);	
	}
	
	for ( int i = 0; i < m; i ++)
	{
		int goal = product[i];
		
		if ( has.count(goal))
		{
			printf("%02d -> %02d\n", goal, goal);
			has.erase(goal);
		}
		else
		{
			auto path = map[goal];
			
			vector<int> rect[100];
			int idx = 0;
			for (auto p: path)
			{
				if ( dfs(p))
				{
					for ( auto x: p) get(x, rect[idx]);
					idx ++;
				}
			}
			
			sort(rect, rect + 100);
			
			
			int cnt = 0, index = 0;
			while ( rect[index].size() == 0) index ++;
		//	for ( int j = 0; j < n; j ++)
		//	{
		//		bool flag = false;
		//		for ( int k = 0; k < idx; k ++)
		//		{
		//			if ( rect[k].count(rectant[j]))
		//			{
		//				index = k;
		//				flag = true;
		//				break;
		//			}
		//		}
	//			if ( flag) break;
	//		}
			
			vector<int> pathl;
			for ( auto t: rect[index]) pathl.push_back(t);
			sort(pathl.begin(), pathl.end());
			
			
			for ( int j = 0; j < pathl.size(); j ++)
			{
				if ( j != pathl.size() - 1) printf("%02d + ", pathl[j]);
				else printf("%02d", pathl[j]);
				
				has.erase(pathl[j]);
			}
			
			
			
			//for ( int j = 0; j < n; j ++)
			//{
				//if ( rect[index].count(rectant[j]))
				//{
				//	if ( cnt != rect[index].size() - 1) printf("%02d + ", rectant[j]);
				//	else printf("%02d", rectant[j]);
					
				//	cnt ++;
				//	has.erase(rectant[j]);
			//	}
		//	}
			
			printf(" -> %02d\n", goal);
		}
	}
	
	return 0;
}

此代码可以忽略,又臭又长,纯属记录。
hhh,纯属流水账记录自己的考试过程,方便自己以后回顾一下,如果能给看文章的各位一点点的经验的话,那就更加有意义啦。强烈推荐acwing,一个超好的算法学习网站。

标签:map,PAT,int,++,2020,劝退,line,include,size
来源: https://blog.csdn.net/weixin_45760941/article/details/111120340