USACO铜级模拟测试(二)
T1:奶牛唱歌
Bessie 按照一种自定义的字母顺序唱"牛文字母歌",Farmer John 记录了听到的部分字母(可能漏掉一些),要求计算 Bessie 至少完整唱完多少遍歌。
解题思路:遍历 John 听到的每个字母,判断其在新字母表中的位置是否在上一字母之后;若不在,说明开启了新的一遍,结果加一。
#include <bits/stdc++.h>
using namespace std;
string order;
char ch;
int cnt = 0, prevPos = -1;
int main() {
freopen("herd.in", "r", stdin);
freopen("herd.out", "w", stdout);
cin >> order;
while (cin >> ch) {
int pos = order.find(ch, prevPos + 1);
if (pos == -1) {
cnt++;
prevPos = order.find(ch);
} else {
prevPos = pos;
}
}
cout << cnt + 1 << endl;
fclose(stdin);
fclose(stdout);
return 0;
}
T2:照片分组
将奶牛分组排序,要求第一组总和为偶、第二组为奇……交替进行。求最大分组数。
解题核心:只关心数字奇偶性。偶数记为e,奇数记为o。最优情况是e与o平衡或e比o多1。若不平衡,通过"两奇变一偶"或"两偶变一偶"调整。
#include <bits/stdc++.h>
using namespace std;
int n, even = 0, odd = 0, val;
int main() {
freopen("group.in", "r", stdin);
freopen("group.out", "w", stdout);
scanf("%d", &n);
for (int i = 0; i < n; ++i) {
scanf("%d", &val);
if (val % 2 == 0) even++;
else odd++;
}
while (even != odd && even != odd + 1) {
if (even > odd + 1) {
even--;
} else {
odd -= 2;
even++;
}
}
printf("%d\n", even + odd);
fclose(stdin);
fclose(stdout);
return 0;
}
T3:牛舍安排
N头奶牛,高度a[i];N个牛棚,高度限制b[i]。将每头奶牛分配到不同牛棚且满足高度约束,求分配方案数。
核心解法:将b升序排序,对每个b[i]统计能装下的奶牛数c[i]。利用乘法原理:第i个牛棚的可选奶牛数为c[i] - (i-1)(因为前面已占用i-1头)。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n, a[30], b[30], cap[30];
int main() {
freopen("stalling.in", "r", stdin);
freopen("stalling.out", "w", stdout);
scanf("%d", &n);
for (int i = 0; i < n; ++i) scanf("%d", &a[i]);
for (int i = 0; i < n; ++i) scanf("%d", &b[i]);
sort(b, b + n);
for (int i = 0; i < n; ++i) {
int cnt = 0;
for (int j = 0; j < n; ++j) {
if (a[j] <= b[i]) cnt++;
}
cap[i] = cnt;
}
ll ans = cap[0];
for (int i = 1; i < n; ++i) {
ans *= max(0, cap[i] - i);
}
printf("%lld\n", ans);
fclose(stdin);
fclose(stdout);
return 0;
}