PAT冬季2020
第一题
给出一个数n,寻找斐波那契数列中与它最近的数。
斐波那契数列以及比较,比较简单,暴力遍历即可。
#include<iostream>
using namespace std;
const int N = 1e5 + 10;
int n,q[N] = {0,1};
int f()
{
for(int i = 2; i < N; ++ i)
{
q[i] = q[i - 1] + q[i - 2];
if(q[i] > n)
{
return q[i] - n >= n - q[i-1] ? q[i - 1]: q[i];
}
}
}
int main()
{
cin >> n;
cout <<f();
return 0;
}
第二题
寻找给定序列的子序列中包含某一子字符串的最小子字符串。
暴力搜索也能过,不过还是需要优化结果,下次做时间限制更小的题才能ac。
//暴力写法
#include<iostream>
#include<string>
using namespace std;
int main() {
string s, sub, res;
cin >> s >> sub;
int len = 1e5,sl = sub.length(),l = s.length();
for (int i = 0; i + sl <= l; i++) {
int pos = 0, j = i;
for (; j < l && pos < sl; j++) {
if (s[j] == sub[pos])
++pos;
}
if (pos == sl) {
if (j - i < len) {
len = j - i;
res = s.substr(i, j - i);
}
}
}
cout << res<<endl;
return 0;
}
第三题
文件管理系统,类似栈的方式来存储树形结果,记得在每次返回上级时改变最终的前缀地址值。
#include<iostream>
#include<vector>
#include<string>
#include<map>
using namespace std;
const int N = 1e3 + 10;
string tmp;
int n,cnt = 0,m;
map<string,int> mp;
vector<string> all;
struct node
{
vector<string> path;
}Nodes[N];
string getstr(string s,int & d)
{
string res ="";
for(int i = 0; i < s.length(); ++ i)
{
if(s[i] != ' ')
res += s[i];
else
d = i + 1;
}
return res;
}
int main()
{
cin >> n;
vector<string> paths;
int pred = 0,curd = 0;
cin.get();
for(int i = 0; i < n; ++ i)
{
pred = curd;
getline(cin, tmp);
if(i == 0) paths.push_back(tmp);
string res = getstr(tmp,curd);
if(curd > pred)
{
paths.push_back(res);
}
else
{
paths[curd] = res;
for(int i = 0; i < pred - curd;++ i)
paths.erase(paths.begin() + paths.size());
}
Nodes[cnt].path = paths;
mp[res] = cnt++;
}
cin >> m;
while(m --)
{
string stmp;
cin >> stmp;
if(mp.find(stmp) != mp.end())
{
vector<string> vtmp = Nodes[mp[stmp]].path;
for(int i = 0; i < vtmp.size(); ++ i)
{
if(i >0) cout<<"->";
cout<< vtmp[i];
}
}
else
{
cout<<"Error: "<<stmp<<" is not found.";
}
cout << endl;
}
return 0;
}
第四题
大型模拟题,用来分配化学方程式的反应物,来得到所有需要的生成物。主要是对所有的反应物进行排序,恰好反应方程式中所有的反应物都是按照顺序排序的。如果非顺序排序,那么该题只能用散列表的方式来存储反应物,然后按照散列中的true/false值来判断是否使用过。
注意一点:因为每次判断是会改变使用状态,但是如果最终该结果没有被使用。(比如 01 + 02 > 08,在02处判断出错)。那么应该将01的使用状态置回false。
#include<iostream>
#include<vector>
#include<string>
#include<map>
#include<algorithm>
using namespace std;
const int N = 30, M = 20,K= 60;
int n,m,k;
string chemical[N],product[M];
bool used[N];
vector<string> v[K];
int cnt = 0;
map<string,vector<int> > mp;
void transfer(string tmp)
{
for(int i = 0; i < tmp.size(); ++ i)
{
if(tmp[i] == '+')
{
v[cnt].push_back(tmp.substr(i - 3, 2));
}
else if(tmp[i] == '-')
{
v[cnt].push_back(tmp.substr(i - 3,2));
if(mp.find(tmp.substr(i + 3,2)) == mp.end())
{
vector<int> vec;
vec.push_back(cnt);
mp[tmp.substr(i + 3,2)] = vec;
}
else
mp[tmp.substr(i + 3,2)].push_back(cnt);
break;
}
}
cnt ++ ;
}
bool cmp1(string s1,string s2)
{
return s1< s2;
}
bool cmp(vector<string> v1,vector<string> v2)
{
int len = v1.size()> v2.size() ? v2.size(): v1.size(), i = -1;
while(++i < len)
{
if(v1[i] != v2[i])
return v1[i] < v2[i];
}
}
int main()
{
cin >> n;
string name;
for(int i = 0 ;i < n; ++ i)
{
cin >> name;
chemical[i] = name;
}
sort(chemical,chemical + n,cmp1);
cin >> m;
for(int i = 0; i < m; ++ i)
{
cin >> name;
product[i] = name;
}
cin >> k;
string tmp;
cin.get();
for(int i = 0;i < k ;++ i)
{
getline(cin,tmp);
transfer(tmp);
}
for(int i = 0; i < m; ++ i)
{
vector<int> pos = mp[product[i]];
vector<string> temp[M];
for(int j = 0; j < pos.size(); ++ j)
temp[j] = v[pos[j]];
sort(temp,temp + pos.size(),cmp);
bool is = false;
for(int j = 0; j < pos.size(); ++j)
{
vector<int> vstr;
int t = 0;
for(int z = 0; z < n; ++ z)
{
if(chemical[z] == temp[j][t] && !used[z])
{
t++;
vstr.push_back(z);
used[z] = true;
if( t == temp[j].size())
break;
}
}
if( t == temp[j].size())
{
is = true;
cout<<temp[j][0];
for(int k = 1; k < temp[j].size(); ++ k)
{
cout<<" + "<< temp[j][k];
}
cout<<" -> "<< product[i]<<endl;
break;
}
for(int k = 0; k <vstr.size(); ++ k)
used[vstr[k]] = false;
}
if(!is)
{
for(int k = 0; k < n; ++ k)
if(product[i] == chemical[k])
used[k] = true;
cout<<product[i] <<" -> " << product[i]<<endl;
}
}
return 0;
}