PAT甲级刷题记录-(AcWing)-Day10(DP 1题 哈希表 8题)
课程来源AcWing
其中AcWing中的题目为翻译好的中文题目
刷题列表
1007 Maximum Subsequence Sum
注意点
DP的思想,但是甲级好像不考这个,先放一放
#include<iostream>
using namespace std;
const int N = 10010;
int w[N], k;
int main() {
cin >> k;
for (int i = 1; i <= k; i++) cin >> w[i];
int res = -1, l = 0, r = 0;
for (int i = 1, f = 0, start = i; i <= k; i++) {
if (f < 0) f = 0, start = i;
f += w[i];
if (res < f) {
l = w[start];
r = w[i];
res = f;
}
}
if (res < 0) res = 0, l = w[1], r = w[k];
cout << res << " " << l << " " << r << endl;
return 0;
}
1048 Find Coins
英语单词
解析
注意点
#include <iostream>
#include <unordered_set>
#include <climits>
using namespace std;
unordered_set<int> set;
int w[100010], n, m;;
bool check(int target) {
int con;
for (int i = 0; i < n; ++i) {
if (w[i] == target) con++;
}
if (con >= 2) return true;
return false;
}
int main() {
cin >> n >> m;
for (int i = 0; i < n; ++i) {
int x;
cin >> x;
w[i] = x;
set.insert(x);
}
// 找 v1 + v2 = m
int v1 = INT_MAX, v2;
for (int i = 0; i < n; ++i) {
int target = m - w[i];
if (target == w[i]) {
if (check(target)) {
if (v1 > min(target, w[i])) v1 = min(target, w[i]), v2 = max(target, w[i]);
}
} else {
if (set.count(target)) {
if (v1 > min(target, w[i])) v1 = min(target, w[i]), v2 = max(target, w[i]);
}
}
}
if (v1 == INT_MAX) puts("No Solution");
else cout << v1 << " " << v2 << endl;
return 0;
}
法二, 在输入的过程中判断是否存在另一个数
#include <iostream>
#include <unordered_set>
#include <climits>
using namespace std;
unordered_set<int> set;
int w[100010], n, m;;
bool check(int target) {
int con;
for (int i = 0; i < n; ++i) {
if (w[i] == target) con++;
}
if (con >= 2) return true;
return false;
}
int main() {
cin >> n >> m;
// 找 v1 + v2 = m
int v1 = INT_MAX, v2;
for (int i = 0; i < n; ++i) {
int x;
cin >> x;
int y = m - x;
if (set.count(y)) {
if (x > y) swap(x, y);
if (x < v1) v1 = x, v2 = y;
}
set.insert(x);
}
if (v1 == INT_MAX) puts("No Solution");
else cout << v1 << " " << v2 << endl;
return 0;
}
1063 Set Similarity
注意点
可以用for(int x:s)
;来遍历set
#include <iostream>
#include <unordered_set>
using namespace std;
unordered_set<int> S[60];
void func(int a, int b) {
// 计算集合a和b的系数
unordered_set<int> S1 = S[a];
unordered_set<int> S2 = S[b];
int nc = 0;
for (auto x:S1) {
nc += S2.count(x);
}
int nt = S1.size() + S2.size() - nc;
printf("%.1lf%%\n", nc * 1.0 / nt * 100);
}
int main() {
int n;
cin >> n;
for (int i = 1; i <= n; ++i) {
int m;
cin >> m;
while (m--) {
int x;
cin >> x;
S[i].insert(x);
}
}
int k;
cin >> k;
while (k--) {
int a, b;
cin >> a >> b;
func(a, b);
}
return 0;
}
1120 Friend Numbers
英语单词
解析
注意点
set
自带排序和去重的效果
#include <iostream>
#include <set>
using namespace std;
int n;
set<int> s;
int main() {
cin >> n;
for (int i = 0; i < n; ++i) {
string number;
cin >> number;
int sum = 0;
for (auto &c:number) {
sum += c - '0';
}
s.insert(sum);
}
cout << s.size() << endl;
bool is_first = true;
for (auto x:s) {
if (is_first) is_first = false;
else cout << " ";
cout << x;
}
return 0;
}
1144 The Missing Number
英语单词
解析
注意点
报了两次错,是因为循环的时候上界开的不够大,后来换成INT_MAX
就对了
这里也可以用while
做
#include <iostream>
#include <unordered_set>
#include <climits>
using namespace std;
int n;
unordered_set<int> set;
int main() {
cin >> n;
for (int i = 0; i < n; ++i) {
int x;
cin >> x;
set.insert(x);
}
for (int i = 1; i < INT_MAX; ++i) {
if (!set.count(i)) {
cout << i << endl;
break;
}
}
return 0;
}
1149 Dangerous Goods Packaging
#include <iostream>
#include <unordered_set>
using namespace std;
int n, m, k;
struct danger {
int a, b;
} danger[10010];
int main() {
cin >> n >> m;
for (int i = 0; i < n; ++i)cin >> danger[i].a >> danger[i].b;
while (m--) {
cin >> k;
unordered_set<int> set;
while (k--) {
int x;
cin >> x;
set.insert(x);
}
bool res = true;
for (int i = 0; i < n; ++i) {
if (set.count(danger[i].a) && set.count(danger[i].b)) {
res = false;
break;
}
}
if (res) puts("Yes");
else puts("No");
}
return 0;
}
1078 Hashing
英语单词
- Quadratic probing (with positive increments only) is used to solve the collisions. 二次探测(只有正增量)被用来解决碰撞。
注意点
- 在判断素数的时候要注意如果
x=1
的情况,要直接返回false
- 使用平方探测法进行插入时,
i
的最大值为size(table)-1
#include <iostream>
using namespace std;
int m_size, m;
bool is_prime(int x) {
if (x == 1) return false;
for (int i = 2; i <= x / i; ++i) {
if (x % i == 0) return false;
}
return true;
};
bool visit[10010];
int find(int x) {
int pos = x % m_size;
if (!visit[pos]) return pos;
for (int i = 0; i < m_size; ++i) {
int t = (pos + i * i) % m_size;
if (!visit[t]) return t;
}
return -1;
}
int main() {
cin >> m_size >> m;
while (!is_prime(m_size)) m_size++;
bool is_first = true;
for (int i = 0; i < m; ++i) {
int x;
cin >> x;
int pos = find(x);
if (is_first) is_first = false;
else cout << " ";
if (pos == -1) cout << "-";
else cout << pos, visit[pos] = true;
}
return 0;
}
1145 Hashing - Average Search Time
英语单词
解析
注意点
平均查找时间除的是查找的数的个数
#include <iostream>
const int N = 10010;
using namespace std;
int s, n, m;
int h[N];
int count;
bool prime(int x) {
if (x == 1) return false;
for (int i = 2; i <= x / i; ++i) {
if (x % i == 0) return false;
}
return true;
}
int find(int x, int &cnt) {
int pos = x % s;
cnt = 1;
if (!h[pos] || h[pos] == x) return pos;
for (int i = 1; i < s; ++i) {
cnt++;
int t = (pos + i * i) % s;
if (!h[t] || h[t] == x)return t;
}
return -1;
}
int main() {
cin >> s >> n >> m;
while (!prime(s)) s++;
while (n--) {
int x, cnt;
cin >> x;
int pos = find(x, cnt);
if (pos == -1) printf("%d cannot be inserted.\n", x);
else h[pos] = x;
}
count = 0;
int length = m;
while (m--) {
int x, cnt;
cin >> x;
int pos = find(x, cnt);
if (pos == -1) count += s + 1;
else count += cnt;
}
printf("%.1lf", count * 1.0 / length);
return 0;
}
1137 Final Grading
#include <iostream>
#include <unordered_map>
#include <vector>
#include <cmath>
#include <algorithm>
using namespace std;
struct Student {
string id;
int p, mid, final, total;
Student() : p(-1), mid(-1), final(-1), total(0) {
};
void cal() {
if (final >= mid) total = final;
else total = round(mid * 0.4 + final * 0.6);
}
bool operator<(const Student &s) {
if (total != s.total) return total > s.total;
return id < s.id;
}
};
unordered_map<string, Student> map;
vector<Student> res;
int main() {
int p, m, n;
string id;
int score;
cin >> p >> m >> n;
while (p--) {
cin >> id >> score;
map[id].id = id; // 如果map中没有id,会根据构造函数创建一个Student对象
map[id].p = score;
}
while (m--) {
cin >> id >> score;
map[id].id = id; // 如果map中没有id,会根据构造函数创建一个Student对象
map[id].mid = score;
}
while (n--) {
cin >> id >> score;
map[id].id = id; // 如果map中没有id,会根据构造函数创建一个Student对象
map[id].final = score;
}
for (auto &item:map) {
auto stu = item.second;
stu.cal();
if (stu.total >= 60 && stu.p >= 200) res.push_back(stu);
}
sort(res.begin(), res.end());
for (int i = 0; i < res.size(); ++i) {
auto stu = res[i];
cout << stu.id << " " << stu.p << " " << stu.mid << " " <<
stu.final << " " << stu.total << endl;
}
return 0;
}