首页 > 其他分享 >【题目全解】ACGO排位赛#10

【题目全解】ACGO排位赛#10

时间:2024-07-16 23:20:20浏览次数:13  
标签:10 arr 面包 int 排位赛 edges que 全解 include

自我反省:确实这次比赛没考好(问题不大,至少排位分没掉)。

第一题 - A24630.ASCII 码

题目链接跳转:A24630.ASCII 码

直接用 C++ 内置的类型转换工具就可以了,(char) 可以将任意的数字转换成一个字符(其实字符底层就是用数字存储的)。

本题的 AC 代码如下:

#include <iostream>
using namespace std;

int main(){
    int n;
    cin >> n;
    cout << (char)n << endl;
	return 0;
}

第二题 - A24631.挑食的小码君

题目链接跳转:A24631.挑食的小码君

做题思路:遍历两遍,第一次遍历通过 maxi 变量记录这些食物中最大的美味值。之后遍历小码君所有不喜欢的食物,判断某项食物的美味值是否等于 maxi

代码很简单,本题的 AC 代码如下:

#include <iostream>
using namespace std;

int n, k, maxi;
int arr[105];

int main(){
    cin >> n >> k;
    for (int i=1; i<=n; i++){
        cin >> arr[i];
        maxi = max(maxi, arr[i]);
    }
    for (int i=1, t; i<=k; i++){
        cin >> t;
        if (arr[t] == maxi){
            cout << "Yes" << endl;
            return 0;
        }
    }
    cout << "No" << endl;
    return 0;
}

第三题 - A24632.奇怪的机器

题目链接跳转:A24632.奇怪的机器

数据量不大,直接模拟和暴力枚举就行了。枚举全部数字变成 \(k\) 所需要花费的最少时间。

在枚举的过程中需要注意的是,由于在一秒之内小码君只能按下一个按钮,因此如果一个数字 \(a\) 在某一列出现了 \(x\) 次,那么当枚举 \(k=a\) 的时候,需要多经过 \((x - 1) \times 10\) 轮才可以把这些转盘(在同一列都出现了 \(x\) 次)变成相同的数字。

本题的 AC 代码如下:

#include <iostream>
#include <algorithm>
using namespace std;

int n, result = 0x7f7f7f7f;
string arr[105];

int query(int pos, int num){
    int ans = 0;
    for (int i=1; i<=n; i++){
        if (arr[i][pos] == num + '0') 
            ans += 1;
    }
    return ans;
}

signed main(){
    cin >> n;
    for (int i=1; i<=n; i++) cin >> arr[i];
    // 暴力枚举:枚举全都变成数字 $k$ 所需要花费的最小时间。
    for (int k=0; k<=9; k++){
        int ans = 0;
        for (int i=1; i<=n; i++){
            // 查询某个数在某一列出现了几次。
            int tmp = query(arr[i].find(k + '0'), k);
            int time = (tmp - 1) * 10 + arr[i].find(k + '0');
            ans = max(time, ans);
        }
        result = min(result, ans);
    }
    cout << result << endl;
}

第四题 - A24633.独特三元组

题目链接跳转:A24633.独特三元组

这道题有很多做法,这里提供一个基于排列组合的算法。

假设有 \(N\) 个元素,且每个元素各不相同,那么满足题目要求的三元组数量就是这 \(N\) 个元素中任意取 \(3\) 个元素的组合。也就是 \(\binom{n}{3} = n \times (n-1) \times (n-2) / 1\)​。

如果有重复的元素呢?我们只需要把重复的元素再“去除”掉就行。

具体地说,如果某个元素的出现次数 arr[i] 大于等于 \(3\),则可以从这些重复的元素中选出三个元素组成一个三元组 \((A_i,A_i,A_i)\),这是不符合条件的,因此再删除掉这些重复元素的组合数即可。即 \(\binom{arr[i]}{3}\)。

如果某个元素的出现次数 arr[i] 大于等于 \(2\),则可以从这些重复的元素中选出两个元素,再从数组中的其他元素中选出一个不同的元素组成三元组 \((A_i,A_i,A_j)\),其中 \(A_i \neq A_j\),即 \(\binom{arr[i]}{2}\)​。

最后本题的 AC 代码如下:

#include <iostream>
#include <algorithm>
#include <cstring>
#define int long long
using namespace std;

const int N = 2e5 + 5;
int n, ans, arr[N];

signed main(){
    cin >> n;
    ans = n * (n-1) * (n-2) / 6;
    for (int i=1, t; i<=n; i++){
        cin >> t;
        arr[t] += 1;
    }  
    for (int i=1; i<=N-1; i++){
        int p1 = 0, p2 = 0;
        if (arr[i] == 0) continue;
        if (arr[i] >= 3) p1 = arr[i] * (arr[i] - 1) * (arr[i] - 2) / 6;
        if (arr[i] >= 2) p2 = (n - arr[i]) * arr[i] * (arr[i] - 1) / 2;
        ans -= p1 + p2;
    }
    cout << ans << endl;
    return 0;
}

第五题 - A24634.道路削减

题目链接跳转:A24634.道路削减

前言:刚开始看这道题目的时候看成了最小生成树的模板题目,盲目的 wsq 随手打了一篇最小生成树的代码交上去,荣获满堂红(葬送了好多次提交记录,真是个悲惨的事情)。

最短路树的模板题目,在 Dijkstra 求最短路径的基础上,记录每一个顶点的“前驱边”就行了。更进一步地,如果松弛了某一条边 \(E(A, B)\),可以使得从源点到达 \(B\) 点的最短距离缩短,那么就保留这一条边(覆盖掉原本通往 \(B\) 点的前驱边即可,一开始没有可以设置为无穷大或者是一个无意义的数字)。可以证明,如果有 \(N\) 个顶点,排除源点,当每一个顶点都有一个前驱边时,图上正好只有 \(N-1\) 条边。且每一个点到源点的距离都是最小的。

PS:本题的数据量比较大,一定要开 long long 数据类型,同时在计算最短路初始化的时候,切记无穷大要开的大一点。

本题的 AC 代码如下:

#include <iostream>
#include <queue>
#include <algorithm>
#include <unordered_map>
#define int unsigned long long
using namespace std;

const int M = 2e5 + 10;
int n, m, ei, vertex[M];
struct node{
    int to, next;
    int weight, id;
} edges[M * 2]; 
struct Node {
    int vertex, distance;
    bool operator>(const Node& other) const {
        return distance > other.distance;
    }
};
int dis[M], fa[M], road[M];

void add(int v1, int v2, int weight, int id){
    ei += 1;
    edges[ei].to = v2;
    edges[ei].weight = weight;
    edges[ei].next = vertex[v1];
    edges[ei].id = id;
    vertex[v1] = ei;
}

void dijkstra(){
    for (int i=1; i<=n; i++){
        dis[i] = 1e15;
        fa[i] = -1;
    }
    dis[1] = 0;
    priority_queue<Node, vector<Node>, greater<Node>> que;
    que.push((Node){1, 0});
    while(que.size()){
        Node t = que.top();
        que.pop();
        int u = t.vertex;
        if (t.distance > dis[u]) continue;
        for (int index=vertex[u]; index; index=edges[index].next){
            int v = edges[index].to;
            int weight = edges[index].weight;
            if (dis[u] + weight < dis[v]){
                dis[v] = dis[u] + weight;
                fa[v] = u; 
                road[v] = edges[index].id;
                que.push((Node){v, dis[v]});
            }
        }
    }
    return ;
}

signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    cin >> n >> m;
    for (int i=1, u, v, w; i<=m; i++){
        cin >> u >> v >> w;
        add(u, v, w, i); add(v, u, w, i);
    }
    dijkstra();
    for (int i=1; i<=n; i++) {
        if (i != 1 && fa[i] != -1) {
            cout << road[i] << " ";
        }
    }
    return 0;
}

第六题 - A24635.分面包

题目链接跳转:A24635.分面包

这道题正着思考比较麻烦,但可以反着思考(选择从小面包逐步拼成大面包,而不是从大面包逐步切割成小面包)。不难发现反着思考后就是一个典型的贪心问题(哈夫曼树)。假设现在有 \(N\) 块长度不一的小面包,那么将这些小面包合并成稍大一些的面包的最优策略就是选择剩下的小面包中长度最短的两块进行合并。每次合并的代价是两个面包的长度之和。通过这种方式,可以确保每次合并的代价最小,从而最终达到最小的总花费。

为了实现这个过程,我们可以使用一个优先队列(最小堆)来维护当前所有待合并的面包。每次从队列中取出两个长度最小的面包进行合并,并将合并后的新面包重新加入到队列中。如此反复,直到队列中只剩下一个面包。

接下来,考虑如何处理“每个孩子 \(i\) 必须收到一个长度正好为 \(A_i\) 的面包”这个要求。如果原始面包长度 \(L\) 大于这些长度之和,则将多余的部分 \(L - \sum A_i\) 也加入到队列中。代表“多出来的部分”也需要被单独分割出来。

本题的 AC 代码如下:

#include <iostream>
#include <queue>
using namespace std;
#define int long long

int L, N, sum;
priority_queue<int, vector<int>, greater<int> > que;

void solve(){
    int total = 0;
    bool flag = 1;
    if (L != sum)
        que.push(L - sum);
    while(que.size() > 1){
        int a = que.top(); que.pop();
        int b = que.top(); que.pop();
        total += a + b;
        que.push(a + b);
    }
    cout << total << endl;
    return ;
}

signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    cin >> N >> L;
    for (int i=1, t; i<=N; i++){
        cin >> t;
        sum += t;
        que.push(t);
    }
    solve();
    return 0;
}

标签:10,arr,面包,int,排位赛,edges,que,全解,include
From: https://www.cnblogs.com/Macw07/p/18306316

相关文章

  • Win10+Docker配置TensorRT环境
    1.Docker下载和安装        Docker下载:InstallDockerDesktoponWindows          Docker安装:勾选直接下一步就行,安装完成后需要电脑重启。         重启后,选择Accept—>Continuewithoutsigningin—>skipsurvey.         可......
  • redis学习-10(集群)
    数据部分rediscluster采用哈希分区规则,具体为虚拟槽分区,使用分散度好的哈希函数分到一个大范围的整数,每个节点负责一定数量的槽。slot=CRC16(key)&16383特点:解耦数据和节点之间的关系;节点自身维护槽的映射关系,不需要客户端和代理服务维护槽分区元数据;支持节点、槽、键之间的映......
  • 《YOLOv10改进实战专栏》专栏介绍 & 专栏目录
    《YOLOv10改进实战专栏》介绍及目录YOLOv10官方仓库地址专栏地址:点击跳转专栏导航如下:......
  • Python爬虫Post请求返回值为-1000
    今天写了一个简单的爬虫程序,为了爬取kfc官网的餐厅数据,代码如下#ajax的post请求--肯德基官网defcreate_request(page):url='http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx'data={ 'cname':'濮阳', 'pid':'', 'pageIndex':p......
  • P10378 [GESP202403 七级] 交流问题题解
    思路我们把关系想成一张图,每次输入就给两个人连一条边。因为一个人只有两种选择,所以我们在一个联通块内随便找一个点,跑一遍搜索,找出这个联通块内的答案。代码如下。voiddfs(intu,intcolor){cnt2++;//cnt2是这个连通块内的总点数cnt1+=color;//这个是一所学校内......
  • 称重式混合机10g测机数据报表
    什么是称重式混料机?称重混料机使用于注塑和挤出行业需要多种原料按比例作精确混合的使用场合,常用于色母,添加剂,母料,填充料,粉碎回料等混合拌料流程。挤出称重色母,添加剂,母料,填充料,粉碎回料称重计量混合拌料系统高低压料计量喂料系统,挤出称重拉片称重供料系统升级款。在塑料加工......
  • 实训0710
    #面向对象##如何打开md文件1、VSCode,预览窗口可以2、IDEA3、Typora##类和对象类一个模板,一类东西共有特征的抽象属性当变量写在类的语句块中时,可以认作是属性描述某种类型的信息方法类的行为,能做的事情```java<修饰符><返回类型><方法名>([参数列表]){......
  • iOS开发基础108-常见的编程范式
    1.面向过程编程(Process-OrientedProgramming,POP)代码示例(Swift)importUIKitclassViewController:UIViewController{overridefuncviewDidLoad(){super.viewDidLoad()printGreeting()printNumber(num:42)}/......
  • 【大模型】 NVIDIA GPU 架构与性能解析:从V100到H100的进化之路
    NVIDIAGPU架构与性能解析:从V100到H100的进化之路一、GPU架构概览二、GPU核心参数详解三、GPU型号对比四、NVIDIAGPU的互联技术五、案例分析六、结论在人工智能和高性能计算的前沿阵地,GPU(图形处理器)正扮演着越来越重要的角色。尤其是NVIDIA的GPU,凭借其强大的并行......
  • iOS开发基础107-直播
    在iOS平台上,直播技术已经很成熟,有许多强大的第三方框架可以帮助开发者轻松实现直播功能。当前主流的直播第三方框架包括但不限于:LFLiveKit:一款开源的直播推流SDK。PLMediaStreamingKit:由云天存提供的一站式音视频解决方案。AliyunPlayer:阿里云提供的音视频播放解决方案。A......