官方题解 欢乐赛#50 题解

官方题解 | 欢乐赛#50 题解

赛纲介绍

本次题目的总体题目难度如下,各位选手可以借此评估一下自身的技术水平

题目编号 题目名称 题目难度
T1 50! 入门
T2 农场修缮 入门
T3 赛马大会 入门
T4 小明和藏宝库 入门
T5 指针夹角 入门
T6 小明的acm罚时 普及-

T1 50!

题目大意

输出一个表示 50 的图形。

题解思路

直接参考样例输出内容, 逐行输出即可。

参考代码

#include <iostream>
using namespace std;
int main() {
  cout << "###.###" << endl;
  cout << "#...#.#" << endl;
  cout << "###.#.#" << endl;
  cout << "..#.#.#" << endl;
  cout << "###.###" << endl;
}

T2 农场修缮

题目大意

给定一片 n×mn×m 的农田, 现在需要在里面修建一条水平的宽度为 aa 的道路, 并且在 qq 条竖直通路中选择一条。求最终农田能够剩余的面积最大值。

题解思路

为了使得剩余的面积尽量大, 应该选择一条宽度最小的通路,设其宽度为 bb

那么水平的道路占用了 a⋅mam 的面积, 竖直的道路占用了 b⋅nbn , 水平和竖直道路的重叠区域的面积为 a⋅bab

因此答案应该为 n⋅m−a⋅m−b⋅n+a⋅bnmambn+ab

参考代码

#include<bits/stdc++.h>
using namespace std;


int main(){
    int n, m, a, q;
   
    int b = 1e9;
    cin >> n >> m >> a >> q;
     int ans = n * m;
     for(int i = 1; i <= q; i++) {
        int x;
        cin >> x;
        b = min(b, x); //寻找宽度最小的数值
     }
     ans -= a * m + b * n - a * b;
     cout << ans << endl;
}

T3 赛马大会

题目大意

小明和对手都按顺序派出 nn 匹马参加赛马大会, 对于每一场比赛获胜则加 33 分, 平局减 33 分,平局分数不变。

求最终小明的得分。

题解思路

分别将小明的所有马的速度值存在数组 aa 中, 对手的所有的马的速度值存在 bb 中。

然后从 1∼n1∼n 遍历每一场比赛,比较双方马匹的速度值然后修改小明的得分值。

参考代码

#include<bits/stdc++.h>
using namespace std;
int a[100010], b[100010];
int n;
int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++) cin >> a[i]; //小明的马匹速度值
    for(int i = 1; i <= n; i++) cin >> b[i]; //对手的马匹速度值
    int ans = 0;
    for(int i = 1; i <= n; i++) {
        if(a[i] > b[i]) ans += 3; //获胜则加3分
        else if(a[i] < b[i]) ans -= 3;
    }
    cout << ans << endl;
    
}

T4 小明和藏宝库

题目大意

存在 nn 个宝箱, 每个宝箱都有 mm 个密码, 只要输入其中一个就可以打开宝箱。

问有多少个密码可以同时解锁 nn 个宝箱?

题解思路

使用桶数组来存储一下每个密码能够打开的宝箱的数量。 对于每个宝箱, 使得该宝箱的 mm 个密码能够解开的宝箱数量+1.

如果说某个数字能够打开的宝箱数量为 nn, 则说明可以打开所有的宝箱,记录答案 + 1。

参考代码

#include <bits/stdc++.h>
using namespace std;

int n, m;
int cnt[100010];
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n >> m;
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= m; j++) {
            int x;
            cin >> x;
            cnt[x]++; 
        }
    }
    int ans = 0;
    for(int i = 1; i <= 100000; i++) if(cnt[i] == n) ans++;
    cout << ans << endl;
}

T5 指针夹角

题目大意

求 aa 时 bb 分的时针和分针夹角度数。

题解思路

一圈为 360°360° , 一小时 6060 分钟, 因此一分钟为 6°6° ,分针的角度 rbr**b 为 6×b6×b

一天1212 小时, 因此一小时为 30°30° ,当前这一个小时已经过去了 b/60b/60 , 因此时针的角度 rar**a 为 30×a+b/60×3030×a+b/60×30 。

最终记得取相对小的夹角度数输出。

参考代码

#include<bits/stdc++.h>
using namespace std;

int x[1010];
int main(){
    double a, b;
    cin >> a >> b;
    double ra, rb;
    rb = b * 6;
    ra = a * 30 + (b / 60) * 30;
    printf("%.2lf\n", min(abs(ra - rb), 360 - abs(ra - rb))); // 输出相对小的夹角度数
}

T6 小明的ACM罚时

题目大意

在一场acm比赛中, 给定每一个队伍的提交记录。 按照acm的规则将所有的队伍进行排名并且按照排名从高到低输出每一只队伍的编号。

题解思路

使用桶数组来存储一下每个密码能够打开的宝箱的数量。 对于每个宝箱, 使得该宝箱的 mm 个密码能够解开的宝箱数量+1.

需要先比较题数,再比较罚时, 都一直的情况下再比较编号大小,因此显然选择使用结构体排序。

定义结构体存储每个队伍的通过题数, 罚时, 编号。 在排序之后按队伍排名从高到低输出队伍编号。

参考代码

#include <bits/stdc++.h>

using namespace std;
struct node{
    int id, num, fs;
    bool operator < (const node&w) const{  //重载操作符, 也可以手写cmp函数
        if(num != w.num) return num > w.num;
        if(fs != w.fs) return fs < w.fs;   
        return id < w.id;
    }
}d[100010];
int n, m;
int main()
{   
    cin >> n;
    for(int i = 1; i <= n; i++) {
        d[i].id = i;
        cin >> m;
        vector<int> cnt(111);  //存储每一道题的错误提交次数

        for(int j = 1; j <= m; j++) {
            int a, b, c;
            cin >> a >> b >> c;
            if(c == 0) cnt[b]++;
            else {
                d[i].fs += a + 15 * cnt[b]; //对于通过的题目 罚时为通过的罚时 + 15 * 错误的次数
                d[i].num++;
            }
        }
    }
    sort(d + 1, d + 1 + n);
    for(int i = 1; i <= n; i++) {
        cout << d[i].id << ' ';
    }
}
posted @ 2025-07-25 18:14  macw08  阅读(24)  评论(0)    收藏  举报