比赛链接:https://www.luogu.com.cn/contest/219467
聪明猪猪大赛
题解
根据 x x x 所在时间区间,判断对应年应举办多少场比赛,详见参考代码。
参考代码
#include <bits/stdc++.h>
using namespace std;
int a, b, c, d, x, ans;
int main() {
#ifdef ExRoc
freopen("test.txt", "r", stdin);
#endif // ExRoc
cin >> a >> b >> c >> d >> x;
if (x >= a) {
ans += b;
}
if (x >= c) {
ans += d;
}
cout << ans << endl;
return 0;
}
旗鼓相当的对手
题解
两重 for
循环遍历
4
4
4 支队伍的排名,若队伍
A
,
B
A,B
A,B 满足
r
a
n
k
A
1
<
r
a
n
k
B
1
a
n
d
r
a
n
k
A
2
>
r
a
n
k
B
2
rank_{A1}<rank_{B1}~and~rank_{A2}>rank_{B2}
rankA1<rankB1 and rankA2>rankB2 或者
r
a
n
k
A
1
>
r
a
n
k
B
1
a
n
d
r
a
n
k
A
2
<
r
a
n
k
B
2
rank_{A1}>rank_{B1}~and~rank_{A2}<rank_{B2}
rankA1>rankB1 and rankA2<rankB2,则答案
+
1
+1
+1。
参考代码
#include <bits/stdc++.h>
using namespace std;
int x;
int rnk[10][10];
int main() {
#ifdef ExRoc
freopen("test.txt", "r", stdin);
#endif // ExRoc
for (int i = 0; i < 2; ++i) {
for (int j = 0; j < 4; ++j) {
cin >> rnk[i][j];
}
}
int ans = 0;
for (int i = 0; i < 4; ++i) {
for (int j = i + 1; j < 4; ++j) {
if (rnk[0][i] < rnk[0][j] && rnk[1][i] > rnk[1][j]) {
++ans;
continue;
}
if (rnk[0][i] > rnk[0][j] && rnk[1][i] < rnk[1][j]) {
++ans;
continue;
}
}
}
cout << ans << endl;
return 0;
}
古希腊掌管罚时的神
题解
由于题目输入保证给出的是“所有有效提交记录”,所以无需考虑无效提交记录。
对于每一个
b
i
b_i
bi,若为
1
1
1(通过)则将总罚时加上
a
i
a_i
ai(通过该题时的分钟数),若为
0
0
0(不通过)则将总罚时加上
20
20
20。
最后注意数据范围,要用 long long
存总罚时。
参考代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int n, a, b;
LL ans;
int main() {
#ifdef ExRoc
freopen("test.txt", "r", stdin);
#endif // ExRoc
cin >> n;
for (int i = 0; i < n; ++i) {
cin >> a >> b;
if (b == 0) {
ans += 20;
} else {
ans += a;
}
}
cout << ans << endl;
return 0;
}
区区泥土也妄想夺走我的专属宝物
题解
根据输入统计 dirt 率即可,注意 double
类型的输入输出。
参考代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int n, a, x;
double dirt;
int main() {
#ifdef ExRoc
freopen("test.txt", "r", stdin);
#endif // ExRoc
cin >> n;
for (int i = 0; i < n; ++i) {
cin >> a;
dirt = 0;
for (int j = 0; j < a; ++j) {
cin >> x;
dirt += x;
}
printf("%.10lf\n", (a - dirt) / a);
}
return 0;
}
题目名没活了
题解
前置知识:集合 set
(建议自学集合用法,以后会经常使用这种数据结构,参考代码如下)
使用集合(set)对所有通过的题目号去重,当
s
t
a
t
e
i
=
1
state_i=1
statei=1 时将
p
i
d
i
pid_i
pidi 加入集合,最终输出集合大小。
参考代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int n, p, a, b;
set<int> st;
int main() {
#ifdef ExRoc
freopen("test.txt", "r", stdin);
#endif // ExRoc
cin >> n >> p;
for (int i = 0; i < n; ++i) {
cin >> a >> b;
if (b == 1) {
st.insert(a);
}
}
cout << st.size() << endl;
return 0;
}
顽强拼搏奖的四种发法
题解
用一个 bool vis[tid][pid]
数组记录
t
i
d
tid
tid 队是否通过第
p
i
d
pid
pid 题,用 int cnt[pid]
数组记录
t
i
d
tid
tid 队通过的题目数量,按照题意模拟即可。
为保持逻辑清晰,建议每种计算方法独立统计,不依赖上一种计算方法储存的数据。
参考代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1000 + 100;
struct Node {
int tid, pid, state;
};
int n, t, p, k;
Node node[maxn];
int cnt[maxn];
bool vis[maxn][maxn];
// 1. 最后一次 AC 记录所对应的队伍
int solve1() {
for (int i = n; i >= 1; --i) {
if (node[i].state == 1) {
return node[i].tid;
}
}
return -1;
}
// 2. 最后一次有效 AC 记录所对应的队伍
int solve2() {
int last = -1;
memset(vis, 0, sizeof(vis));
for (int i = 1; i <= n; ++i) {
// 过滤掉未通过提交
if (node[i].state == 0) {
continue;
}
// 用 vis 数组判断是否已通过,只有未通过题目的提交才是有效提交
if (!vis[node[i].tid][node[i].pid]) {
vis[node[i].tid][node[i].pid] = true;
// 通过不断更新 last 值获取到满足“最后一次”条件的队伍
last = node[i].tid;
}
}
return last;
}
// 3. 未获得奖牌的队伍的最后一次有效 AC 提交对应的队伍
int solve3() {
// 先统计每支队伍的通过题目数
memset(vis, 0, sizeof(vis));
memset(cnt, 0, sizeof(cnt));
for (int i = 1; i <= n; ++i) {
if (node[i].state == 0) {
continue;
}
if (!vis[node[i].tid][node[i].pid]) {
vis[node[i].tid][node[i].pid] = true;
++cnt[node[i].tid];
}
}
// 再统计最后一次有效提交对应的队伍
int last = -1;
memset(vis, 0, sizeof(vis));
for (int i = 1; i <= n; ++i) {
//过滤掉已获得奖牌的队伍
if (cnt[node[i].tid] >= k) {
continue;
}
// 这部分逻辑与之前完全相同
if (node[i].state == 0) {
continue;
}
if (!vis[node[i].tid][node[i].pid]) {
vis[node[i].tid][node[i].pid] = true;
last = node[i].tid;
}
}
return last;
}
// 4. 最后一次使得一支队伍的通过题目数由 0 变成 1 的提交所对应的队伍
int solve4() {
int last = -1;
memset(vis, 0, sizeof(vis));
memset(cnt, 0, sizeof(cnt));
for (int i = 1; i <= n; ++i) {
if (node[i].state == 0) {
continue;
}
if (!vis[node[i].tid][node[i].pid]) {
vis[node[i].tid][node[i].pid] = true;
++cnt[node[i].tid];
// 满足通过题目数从 0 变成 1 的条件
if (cnt[node[i].tid] == 1) {
last = node[i].tid;
}
}
}
return last;
}
int main() {
#ifdef ExRoc
freopen("test.txt", "r", stdin);
#endif // ExRoc
cin >> n >> t >> p >> k;
for (int i = 1; i <= n; ++i) {
cin >> node[i].tid >> node[i].pid >> node[i].state;
}
cout << solve1() << " " << solve2() << " " << solve3() << " " << solve4() << endl;
return 0;
}
正在联系教练退赛
题解
前置知识:string
类用法(建议自学,常用字符串操作类)
由于数据量较少,可直接使用 string
库函数做字串判断,按题意模拟即可。
参考代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 100 + 100;
int n, m;
string s[maxn], t[maxn];
bool judge(const string &str) {
for (int i = 0; i < m; ++i) {
// find 方法返回 string::npos 时表示无法找到子串
if (str.find(t[i]) != string::npos) {
return true;
}
}
return false;
}
int main() {
#ifdef ExRoc
freopen("test.txt", "r", stdin);
#endif // ExRoc
cin >> n;
for (int i = 0; i < n; ++i) {
cin >> s[i];
}
cin >> m;
for (int i = 0; i < m; ++i) {
cin >> t[i];
}
for (int i = 0; i < n; ++i) {
cout << (judge(s[i]) ? "Yes" : "No") << endl;
}
return 0;
}
吃饭大赛总决赛
题解
前置知识:结构体排序、集合(自学)
将一个每支猪猪队伍的信息
s
0
,
s
1
,
s
2
,
s
3
,
i
d
,
r
s0, s1, s2, s3,id, r
s0,s1,s2,s3,id,r 放到一个结构体里进行排序,排序主关键字为
r
r
r(排名)、副关键字为
i
d
id
id,均为从小到大排序。
使用 set
存所有已晋级 EC final 的猪猪名字,依次按排序后的队伍选择晋级名额时,使用 set
判断成员是否已经晋级,若已晋级则跳过该队伍,否则整支队伍晋级。
参考代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 10000 + 100;
struct Node {
string s0, s1, s2, s3;
int id, r;
};
bool operator<(const Node &a, const Node &b) {
if (a.r == b.r) {
return a.id < b.id;
}
return a.r < b.r;
}
int n, m, t, k;
Node node[maxn];
vector<Node> ans;
set<string> st;
int main() {
#ifdef ExRoc
freopen("test.txt", "r", stdin);
#endif // ExRoc
cin >> n >> m >> t >> k;
for (int i = 0; i < n; ++i) {
cin >> node[i].s0 >> node[i].s1 >> node[i].s2 >> node[i].s3 >> node[i].id >> node[i].r;
}
sort(node, node + n);
for (int i = 0; i < n; ++i) {
if (st.find(node[i].s1) == st.end() &&
st.find(node[i].s2) == st.end() &&
st.find(node[i].s3) == st.end()) {
ans.push_back(node[i]);
st.insert(node[i].s1);
st.insert(node[i].s2);
st.insert(node[i].s3);
--k;
}
if (k == 0) {
break;
}
}
cout << ans.size() << endl;
for (Node &node : ans) {
cout << node.s0 << " " << node.s1 << " " << node.s2 << " " << node.s3 << endl;
}
return 0;
}