PAT グレード A 質問記録-(AcWing)-Day10(DP 1 質問ハッシュ テーブル 8 質問)
このコースは AcWing から提供されており、
AcWing のタイトルは中国語のタイトルに翻訳されています。
ブラシリスト
1007 最大サブシーケンス合計
DPの考え方に注意してください
、しかしクラスAはこのテストを受けないようです、今のところは放っておいてください
#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 コインを探す
英単語
分析する
注意点
#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;
}
方法2、入力途中に他の数字があるかどうかを判断する
#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 類似性を設定する
; を
使用してトラバースできることに注意してください。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 友達番号
英単語
分析する
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 消えた数字
英単語
分析する
サイクル中に上限が十分に大きくなかったため、エラーが 2 回報告されたことに注意してください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 危険物の包装業
#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 ハッシュ
英単語
- 二次関数プローブ (正の増分のみ) を使用して衝突を解決します。 二次関数プローブ (正の増分のみ) を使用して衝突を解決します。
注意点
- 素数判定の際は
x=1
ifの状況に注意して直接返す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 ハッシュ - 平均検索時間
英単語
分析する
平均検索時間を検索数で割った値であることに注意してください。
#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 最終グレーディング
#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;
}