T1:矩形的周长与面积
模拟
代码实现
a, b = map(int, input().split())
print(2*(a+b))
print(a*b)
T2:机会成本
一开始,所有事情认真对待,则拿到 \(\sum b_i\) 的分数
然后如果认真对待第 \(i\) 件事,则拿到 \(a_i - b_i\) 的分数
只需枚举认真对待哪一件事即可
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
int main() {
int n;
cin >> n;
vector<int> a(n), b(n);
rep(i, n) cin >> a[i] >> b[i];
int ans = accumulate(b.begin(), b.end(), 0);
int mx = 0;
rep(i, n) mx = max(mx, a[i]-b[i]);
ans += mx;
cout << ans << '\n';
return 0;
}
T3: 阶乘尾零
\(10\) 的幂次,相当于 \(2\) 的幂次乘以 \(5\) 的幂次
\(n!\) 中 \(2\) 的幂次肯定比 \(5\) 的幂次高
所以我们只需找出 \(n!\) 中 \(5\) 的幂次即可,可以用 legendre
函数来求
代码实现
#include <bits/extc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
// n! 被素数 p 整除了多少次
ll legendre(ll n, int p) {
ll res = 0;
while (n) {
res += n/p;
n /= p;
}
return res;
}
int main() {
ll n;
cin >> n;
cout << legendre(n, 5) << '\n';
return 0;
}
T4:前序中序转后序
递归
代码实现
#include <bits/extc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
void f(string a, string b) {
if (b == "") return;
int p = b.find(a[0]);
f(a.substr(1, p), b.substr(0, p)); // 前一半
f(a.substr(p+1), b.substr(p+1)); // 后一半
cout << a[0];
}
int main() { // a: 前序 b: 中序
string a, b;
cin >> a >> b;
f(a, b);
return 0;
}
T5:三色排序
本题是一个考察数学思维的题目
这些交换,操作,这种有一个过程的题目一般都是需要找到这个操作的核心,然后变成一个数学问题
我们把 \(a\) 数组和结果数组进行比较,如果已经一致了,就没必要再动了,这里体现了一种贪心的想法
记最后升序的数组为 b[]
,对于 \(a[i] \neq b[i]\),且 \(b[i] = 0\) 或 \(2\), 我们记录一分(因为 0
和 2
还原了,自然 1
也就还原了),这样总数组有一个分数
现在对操作进行打分
对于一次操作,最多获得 \(2\) 分(应该是 0
的找到一个 2
,应该是 2
的找到一个 0
,把它们交换一下即可),其余操作最多获得 \(1\) 分
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
inline int read() {
int x = 0;
char c;
while (c < '0' or c > '9') c = getchar();
while ('0' <= c and c <= '9') {
x = x*10+c-'0';
c = getchar();
}
return x;
}
int main() {
int n = read();
vector<int> a(n);
rep(i, n) a[i] = read();
vector<int> cnt(3); // c[i] 表示 i 的个数
rep(i, n) cnt[a[i]]++;
// c: 前 cnt[0] 个数中 1 的个数,d: 前 cnt[0] 个数中 2 的个数
// e: 后 cnt[2] 个数中 0 的个数,f: 后 cnt[2] 个数中 1 的个数
int c = 0, d = 0, e = 0, f = 0;
rep(i, cnt[0]) {
if (a[i] == 1) c++;
if (a[i] == 2) d++;
}
for (int i = n-cnt[2]; i < n; ++i) {
if (a[i] == 0) e++;
if (a[i] == 1) f++;
}
int ans = c+d+e+f-min(d, e);
cout << ans << '\n';
return 0;
}