【LGR-211-Div.4】洛谷入门赛 #30 题解

比赛链接: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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值