雅礼 2023.11.22 习题课记录
雅礼信奥 习题课记录
都是 CF 题,不如 AT。
A - Yarik and Array(CF1899C)
dp 题,作为学 OI 年的萌新 OIer,后面才想到 dp 真是太蒟蒻了,时间复杂度 。
初始 ,其他为 。
状态转移方程:
即为答案。
罚时 次。
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <stack>
using namespace std;
using ll = long long;
const int kMaxN = 2e5 + 20, kInf = (((1 << 30) - 1) << 1) + 1;
ll n, a[kMaxN], f[kMaxN], ans = 0;
int main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t;
for (cin >> t; t; -- t) {
cin >> n;
for (int i = 1; i <= n; ++ i) {
cin >> a[i];
f[i] = 0;
}
f[1] = a[1];
ans = f[1];
for (int i = 2; i <= n; ++ i) {
if (abs(a[i - 1]) % 2 + abs(a[i]) % 2 == 1) {
f[i] = max(a[i], f[i - 1] + a[i]);
ans = max(ans, f[i]);
} else {
f[i] = a[i];
ans = max(ans, f[i]);
}
}
cout << ans << '\n';
}
return 0;
}
B - Game with Integers(CF1899A)
一眼题 + 面向样例题, 输出 Second
,否则 First
,时间复杂度 。
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <stack>
using namespace std;
using ll = long long;
const int kMaxN = 2e5 + 20, kInf = (((1 << 30) - 1) << 1) + 1;
int x;
int main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t;
for (cin >> t; t; -- t) {
cin >> x;
cout << (!(x % 3)? "Second" : "First") << '\n';
}
return 0;
}
C - 250 Thousand Tons of TNT(CF1899B)
枚举题。
首先, 必定是 的因数,所以我们只需要枚举 的因数即可,时间复杂度不确定,好像是 。
罚时 次,因为不开 long long 见祖宗。
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <stack>
using namespace std;
using ll = long long;
const int kMaxN = 2e5 + 20, kInf = (((1 << 30) - 1) << 1) + 1;
ll n, a[kMaxN], b[kMaxN], idx = 0, mini = 1e18, maxa = -1e18, ans = -1e18, sum = 0;
int main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t;
for (cin >> t; t; -- t) {
cin >> n;
idx = 0, ans = -1e18;
for (int i = 1; i <= n; ++ i) {
cin >> a[i];
}
for (ll i = 1; i * i <= n; ++ i) {
if (n % i) {
continue;
}
b[++ idx] = n / i;
mini = 1e18, maxa = -1e18;
for (ll j = 1; j <= n; ++ j) {
sum += a[j];
if (!(j % i)) {
mini = min(mini, sum);
maxa = max(maxa, sum);
sum = 0;
}
}
ans = max(ans, maxa - mini);
}
sum = 0;
for (ll i = 1; i <= idx; ++ i) {
mini = 1e18, maxa = -1e18;
for (ll j = 1; j <= n; ++ j) {
sum += a[j];
if (!(j % b[i])) {
mini = min(mini, sum);
maxa = max(maxa, sum);
sum = 0;
}
}
ans = max(ans, (b[i] == n? 0 : maxa - mini));
}
cout << ans << '\n';
}
return 0;
}
D - Yarik and Musical Notes(CF1899D)
成为一个合法的一对 必须满足 或 , 或 ,,所以我们建立一个哈希表 (一定要开 map
,unoredered_map
被卡了!),如果 ,答案加 ,如果 ,答案加 ,然后每次答案加 。时间复杂度 。
罚时 次,因为 unoredered_map
啊啊啊啊啊!
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <unordered_map>
using namespace std;
using ll = long long;
const int kMaxN = 2e5 + 20, kInf = (((1 << 30) - 1) << 1) + 1;
ll n, a[kMaxN], ans = 0;
int main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t;
for (cin >> t; t; -- t) {
unordered_map<ll, ll> mp;
ans = 0;
cin >> n;
for (int i = 1; i <= n; ++ i) {
cin >> a[i];
if (a[i] == 1) {
ans += mp[2];
}
if (a[i] == 2) {
ans += mp[1];
}
ans += mp[a[i]];
++ mp[a[i]];
}
cout << ans << '\n';
}
return 0;
}
E - Treasure Chest(CF1895A)
分类讨论题,只需稍微推一下就可以。
当初还以为是搜索。
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <stack>
using namespace std;
using ll = long long;
const int kMaxN = -1, kInf = (((1 << 30) - 1) << 1) + 1;
int x, y, k;
int main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t;
for (cin >> t; t; -- t) {
cin >> x >> y >> k;
if (x > y) {
cout << x << '\n';
} else {
if (y - (k + x) <= 0) {
cout << y << '\n';
} else {
cout << x + k + (y - (k + x) << 1) << '\n';
}
}
}
return 0;
}
F - Queue Sort(CF1899E)
首先,我们定义一个 (存最小值)和 (用来记录答案)。每次把 赋值为 , 赋值为 。遍历一遍数组, 记录最小值的下标。如果 区间内有 的情况,输出 ,否则输出 。
罚时 次。
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <stack>
using namespace std;
using ll = long long;
const int kMaxN = 2e5 + 20, kInf = (((1 << 30) - 1) << 1) + 1;
ll n, a[kMaxN], ans = 1e18, cnt = 0;
int main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t;
for (cin >> t; t; -- t) {
cin >> n;
ans = 1e18, cnt = 0;
for (int i = 1; i <= n; ++ i) {
cin >> a[i];
if (a[i] < ans) {
ans = a[i];
cnt = i;
}
}
for (int i = cnt + 1; i <= n; ++ i) {
if (a[i] < a[i - 1]) {
cnt = -1;
}
}
cout << (cnt == -1? -1 : cnt - 1) << '\n';
}
return 0;
}
G - Points and Minimum Distance(CF1895B)
当初还以为是最短路,所以放在后面,结果发现 G 好简单。
将输入的数据排好序,然后遍历 ,每次把距离加 ,遍历完后输出。然后我们定义两个指针 ,,,每次 加 , 减 , 即是我们要输出的坐标。
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <vector>
using namespace std;
using ll = long long;
const int kMaxN = 2e5 + 20, kInf = (((1 << 30) - 1) << 1) + 1;
ll n, ans = 0, a[kMaxN];
int main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t;
for (cin >> t; t; -- t) {
ans = 0;
cin >> n;
for (int i = 1; i <= (n << 1); ++ i) {
cin >> a[i];
}
sort(a + 1, a + (n << 1) + 1);
for (int i = 1; i <= n - 1; ++ i) {
ans += labs(a[i] - a[i + 1]) + labs(a[i + n] - a[i + n + 1]);
}
cout << ans << '\n';
for (int i = 1, j = (n << 1); i <= j; ++ i, -- j) {
cout << a[i] << ' ' << a[j] << '\n';
}
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】