当前位置: 首页 > news >正文

蓝桥杯2024年第十五届省赛真题-宝石组合

题目链接:

暴力思路:

我们通过 DFS 枚举所有的方案,在对每个方案进行判断。因为我们是从小到大开始枚举的,所以如果这个方案的 S 大于了我们维护的最大值,我们就更新最大值,在更新方案。这种做法的时间复杂度为 0(n^3),只能通过 30% 的样例。

暴力代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e5+20;

int n, arr[N];
int ans[N]; //每次存组合数
int res[N], r;

//查找两个数最小公倍数
int find(int x, int y){
    return x*y / __gcd(x, y);
}

void dfs(int x, int start){
    if(x > 3){
        //求s的最大值
        int a = find(ans[1], ans[2]);
        int b = find(ans[2], ans[3]);
        int c = find(ans[1], ans[3]);
        int p1 = find(min(min(a, b),c), max(max(a,b),c));
        int p2 = ans[1] * ans[2] * ans[3];
        int s = p2*p1/(a*b*c);
        if(s > r){
            r = s;
            //更新最大 S 的方案
            for(int i =1; i <= 3; i++){
                res[i] = ans[i];
            }
        }
        return;
    }
    
    for(int i = start; i <= n; i++){
        ans[x] = arr[i];
        dfs(x+1, i+1);
        ans[x] = 0;
    }
}

signed main(){
    cin >> n;
    for(int i = 1; i <= n; i++) cin >> arr[i];
    //排序
    sort(arr+1, arr+1+n);
    dfs(1, 1);
    for(int i =1; i <= 3; i++) cout << res[i] << " ";
    return 0;
}

优化思路:

对S公式的推导视频。

通过对式子的推导,我们知道了,要求 s  的最大值,就转换为找到三枚宝石的最大公因数。

①我们可以先预处理,对 1~1e5+100 的所有数字,找到每个数字的所有公因数,将每个数的所有公因数都存在 vector 中。

②在读入数据,用 cnt 数组记录每个数字的所有公因数出现的次数,我们要找的出现次数大于 3 的最大公因数 k 。

③枚举读入的数据,如果这个数能被最大公因数 k  整除,我们用 ans 容器来记录所有的答案。

④输出答案,我们输出 ans 容器中的前面三个数字, 这就是最小的方案。

代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e5+10;

int n, arr[N];
//该数组中存得是 1~N 中每个数得所有公因数
vector<int> q[N];
//该数组中存得是 数据 中每个数 公因数出现的次数
int cnt[N];
//出现个数大于3的最大公因数
int k;
//该数组存的是数据中能被最大公因数整除的所有答案
vector<int> ans;

signed main(){
    cin >> n;
    //先对 1~N 预处理,找到每个数的所有公因数
    for(int i = 1; i<= N; i++){
        //保证每次将得都是 i 得倍数
        for(int j = i; j <= N; j+=i){
            //将 j 得公因数全部存入到 q[j]中
            q[j].push_back(i);
        }
    }
    //读入数据
    for(int i = 1; i <= n; i++){
        cin >> arr[i];
        for(auto x: q[arr[i]]){
            //公因数出现的次数加1
            cnt[x] ++;
        }
    }
    // 在 cnt 中找到出现个数大于3 的最大公因数
    for(int i = 1; i <= N; i++){
        if(cnt[i] >= 3){
            k = i;
        }
    }
    
    //对数组排序
    sort(arr+1, arr+1+n);
    //在数组中找到能被最大公因数整除的数, 并将它存入到 ans 中找到出现个数大于3
    for(int i = 1; i <= n; i++){
        if(arr[i] % k == 0){
            ans.push_back(arr[i]);
        }
    }
    
    //输出ans数组中的前面三个答案
    for(int i = 0; i < 3; i++){
        cout  << ans[i]<< " ";
    }
    return 0;
}

http://www.dtcms.com/a/113653.html

相关文章:

  • BGP路由协议之特殊配置
  • Linux内核slab分配器
  • Linux 系统安装与优化全攻略:打造高效开发环境
  • Airflow量化入门系列:第四章 A股数据处理与存储优化
  • 浅谈StarRocks 常见问题解析
  • (5)模拟后——Leonardo的可视化操作
  • 探秘叁仟智盒设备:智慧城市的智能枢纽
  • Django4.0 快速集成jwt
  • ASP.NET Core Web API 参数传递方式
  • NLP简介及其发展历史
  • docker stack常用命令
  • C#结构体(Struct)深度解析:轻量数据容器与游戏开发应用 (Day 20)
  • pinia-plugin-persist、vuex
  • Spring Boot项目连接MySQL数据库及CRUD操作示例
  • Java Timer:老派但好用的“定时任务小闹钟“
  • 【Linux】进程间通信、匿名管道、进程池
  • 将OpenFOAM中的lduMatrix数据转换为CSC稀疏矩阵格式
  • 混合编程的架构
  • Java EE期末总结(第三章)
  • Leedcode刷题 | 回溯算法小总结01
  • kali——masscan
  • Matlab轴承故障信号仿真与故障分析
  • spring-cloud-alibaba-nacos-config使用说明
  • 《K230 从熟悉到...》无线网络
  • LINUX 4 tar -zcvf -jcvf -Jcvf -tf -uf
  • Transformer+BO-SVM多变量时间序列预测(Matlab)
  • 力扣刷题——508.出现次数最多的子树和
  • Docker存储策略深度解析:临时文件 vs 持久化存储选型指南
  • 每日算法-250405
  • 4. 面向对象程序设计