PAT B1049

news2024/12/23 4:44:13

PAT B1049

题目

给定一个正数数列,我们可以从中截取任意的连续的几个数,称为片段。例如,给定数列 { 0.1, 0.2, 0.3, 0.4 },我们有 (0.1) (0.1, 0.2) (0.1, 0.2, 0.3) (0.1, 0.2, 0.3, 0.4) (0.2) (0.2, 0.3) (0.2, 0.3, 0.4) (0.3) (0.3, 0.4) (0.4) 这 10 个片段。

给定正整数数列,求出全部片段包含的所有的数之和。如本例中 10 个片段总和是 0.1 + 0.3 + 0.6 + 1.0 + 0.2 + 0.5 + 0.9 + 0.3 + 0.7 + 0.4 = 5.0。

输入格式:

输入第一行给出一个不超过 10^5 的正整数 N,表示数列中数的个数,第二行给出 N 个不超过 1.0 的正数,是数列中的数,其间以一个空格分隔。

输出格式:

在一行中输出该序列所有片段包含的数之和,精确到小数点后 2 位。

输入样例:

4
0.1 0.2 0.3 0.4

输出样例:

5.00

尝试:

我的第一眼感觉是一个子集问题,但是它又不是所有的子集,首先打印出所有的子集,根据出现的子集,判断所有子集中,哪些应该存在,哪些不应该存在。

#include <bits/stdc++.h>

using namespace std;

void subsets(vector<double>&arr,vector<double>&path,vector<vector<double> >&res,int k,int n) {
    if (k == n) {
        return;
    }
    path.push_back(arr[k]);
    res.push_back(path);
    subsets(arr, path, res, k + 1, n);
    path.pop_back();
    subsets(arr, path, res, k + 1, n);
}




int main() {
    int n;
    cin>>n;
    vector<double>arr;
    for (int i = 0; i <n ; ++i) {
        double t;
        cin>>t;
        arr.push_back(t);
    }
    vector<double>path;
    vector<vector<double> >res;
    subsets(arr,path,res,0,n);
    for (int i = 0; i < res.size(); ++i){
        for (int j = 0; j <res[i].size() ; ++j) {
            cout<<" ["<<res[i][j]<<"] ";
        }
        cout<<"\n";

    }




    return 0;


}

在输出里,我们需要的子集使用’#'标记

4
0.1 0.2 0.3 0.4
 #[0.1]          
 #[0.1]  [0.2]     
 #[0.1]  [0.2]  [0.3]        
 #[0.1]  [0.2]  [0.3]  [0.4] 
 [0.1]  [0.2]  [0.4]        
 [0.1]  [0.3] 
 [0.1]  [0.3]  [0.4]
 [0.1]  [0.4]
 #[0.2]
 #[0.2]  [0.3]
 #[0.2]  [0.3]  [0.4]
 [0.2]  [0.4]
 #[0.3]
 #[0.3]  [0.4]
 #[0.4]


找到了一个规律,如果path为空,你可以随便放入一个元素,如果不为空,你必须放入path刚放进去的元素的后一位元素(即如果path里最新放入的元素为num[i-1],你就只能放num[i],要么就不放)

这里放入元素还需要记录数组下标,所以我这里使用pair,你也可以自己设计一个结构体,或者直接使用数组当作结构体

#include <bits/stdc++.h>

using namespace std;

void
subsets(vector<double> &arr, vector<pair<int, double> > &path,
        vector<vector<pair<int, double> > > &res, int k, int n) {
    if (k == n) {
        return;
    }
    //如果path为空直接放入
    if (path.size() == 0) {
        path.push_back(make_pair(k, arr[k]));
        res.push_back(path);
        subsets(arr, path, res, k + 1, n);
        path.pop_back();
        subsets(arr, path, res, k + 1, n);
    } else {
        //如果不为空
        if (path[path.size() - 1].first == k - 1) {
            path.push_back(make_pair(k, arr[k]));
            res.push_back(path);
            subsets(arr, path, res, k + 1, n);
            path.pop_back();
            subsets(arr, path, res, k + 1, n);

        }


    }


}


int main() {
    int n;
    cin >> n;
    vector<double> arr;
    for (int i = 0; i < n; ++i) {
        double t;
        cin >> t;
        arr.push_back(t);
    }
    vector<pair<int, double> > path;
    vector<vector<pair<int, double> > > res;
    subsets(arr, path, res, 0, n);

    for (int i = 0; i < res.size(); ++i) {
        for (int j = 0; j < res[i].size(); ++j) {
            cout << " [" << res[i][j].second << "] ";
        }
        cout << "\n";

    }


    return 0;


}

4
0.1 0.2 0.3 0.4
 [0.1]
 [0.1]  [0.2]
 [0.1]  [0.2]  [0.3]        
 [0.1]  [0.2]  [0.3]  [0.4] 
 [0.2]
 [0.2]  [0.3]
 [0.2]  [0.3]  [0.4]        
 [0.3]
 [0.3]  [0.4]
 [0.4] 

实现了选择子集功能

初步实现

#include <bits/stdc++.h>

using namespace std;

void
subsets(vector<double> &arr, vector<pair<int, double> > &path,
        vector<vector<pair<int, double> > > &res, int k, int n) {
    if (k == n) {
        return;
    }
    //如果path为空直接放入
    if (path.size() == 0) {
        path.push_back(make_pair(k, arr[k]));
        res.push_back(path);
        subsets(arr, path, res, k + 1, n);
        path.pop_back();
        subsets(arr, path, res, k + 1, n);
    } else {
        //如果不为空
        if (path[path.size() - 1].first == k - 1) {
            path.push_back(make_pair(k, arr[k]));
            res.push_back(path);
            subsets(arr, path, res, k + 1, n);
            path.pop_back();
            subsets(arr, path, res, k + 1, n);

        }


    }


}


int main() {
    int n;
    cin >> n;
    vector<double> arr;
    for (int i = 0; i < n; ++i) {
        double t;
        cin >> t;
        arr.push_back(t);
    }
    vector<pair<int, double> > path;
    vector<vector<pair<int, double> > > res;
    subsets(arr, path, res, 0, n);
    double sum=0;

    for (int i = 0; i < res.size(); ++i) {
        for (int j = 0; j < res[i].size(); ++j) {
          sum+=res[i][j].second;
        }
    }
    std::printf("%.2f",sum);


    return 0;


}

提交结果:

在这里插入图片描述

内存不够用,需要优化一下代码

初步优化

#include <bits/stdc++.h>

using namespace std;

double check(vector<double> arr, vector<int> path) {
    double tmp = 0;
    for (int i = 0; i < path.size(); ++i) {
        tmp += arr[path[i]];
    }
    return tmp;
}


void
subsets(vector<double> &arr, vector<int> &path,
        double &sum, int k, int n) {
    if (k == n) {
        return;
    }
    //如果path为空直接放入
    if (path.size() == 0) {
        path.push_back(k);
        sum += arr[k];
        subsets(arr, path, sum, k + 1, n);
        path.pop_back();
        subsets(arr, path, sum, k + 1, n);
    } else {
        //如果不为空
        if (path[path.size() - 1] == k - 1) {
            path.push_back(k);
            sum += check(arr, path);
            subsets(arr, path, sum, k + 1, n);
            path.pop_back();
            subsets(arr, path, sum, k + 1, n);

        }


    }


}


int main() {
    int n;
    cin >> n;
    vector<double> arr;
    for (int i = 0; i < n; ++i) {
        double t;
        cin >> t;
        arr.push_back(t);
    }
    vector<int> path;
    double sum = 0;
    subsets(arr, path, sum, 0, n);
    std::printf("%.2f", sum);


    return 0;


}

提交结果:

在这里插入图片描述

这下内存没超,时间超了,还得优化,死磕了呀!!!

把数据结构都删掉再试试

#include <bits/stdc++.h>

using namespace std;

void
subsets(vector<double> &arr, int &last_index,
        double &sum, double &path_sum, int k, int n) {
    if (k == n) {
        return;
    }
    //如果path为空直接放入
    if (last_index == -1) {
        last_index = k;
        path_sum += arr[k];
        sum += arr[k];
        subsets(arr, last_index, sum, path_sum, k + 1, n);
        last_index = -1;
        path_sum -= arr[k];
        subsets(arr, last_index, sum, path_sum, k + 1, n);
    } else {
        //如果不为空
        if (last_index == k - 1) {
            last_index = k;
            path_sum += arr[k];
            sum += path_sum;
            subsets(arr, last_index, sum, path_sum, k + 1, n);
            last_index = k - 1;
            path_sum -= arr[k];
            subsets(arr, last_index, sum, path_sum, k + 1, n);

        }


    }


}


int main() {
    int n;
    cin >> n;
    vector<double> arr;
    for (int i = 0; i < n; ++i) {
        double t;
        cin >> t;
        arr.push_back(t);
    }
    double sum = 0;
    double path_sum = 0;
    int last_index = -1;
    subsets(arr, last_index, sum, path_sum, 0, n);
    std::printf("%.2f", sum);


    return 0;


}

提交结果:

在这里插入图片描述

最后两个还是没过,超时,感觉自己好弱

再次优化

感觉这种搜索有点难过最后两个样例了,得输入的时候就处理数据,在O(n)内就把数据处理完,这样模拟的应该跑不了的,尝试下数学方法规律

#include <bits/stdc++.h>

using namespace std;


int main() {
    int n;
    cin >> n;
    double sum = 0;
    for (int i = 0; i < n; ++i) {
        double t;
        cin >> t;
        sum += t * (n - i) * (i + 1);//样例从左到右要加(4-i)*(i+1)次 比如用第一个元素从左到右一共用4次 只能向右边片段3次本身一次
        //第二个元素前面使用从0开始到4结束使用第二个元素一共使用5次片段 本身用一次 一共六次
    }

    printf("%.2f", sum);


    return 0;


}



提交结果:

在这里插入图片描述

没过,绷不住了

查了下,测试点2错误double的精度不够,易产生误差,数据量足够大误差就会被放大直至小数点后2位也不精确。

最终代码

#include <bits/stdc++.h>

using namespace std;


int main() {
    int n;
    cin >> n;
    long double sum = 0.0;
    for (int i = 0; i < n; ++i) {
       double t;
        cin >> t;
        sum += t * (n - i) * (i + 1);//样例从左到右要加(4-i)*(i+1)次 比如用第一个元素从左到右一共用4次 只能向右边片段3次本身一次
        //第二个元素前面使用从0开始到4结束使用第二个元素一共使用5次片段 本身用一次 一共六次
    }

    printf("%.2f",(double) sum);


    return 0;


}



提交结果:

在这里插入图片描述

终于过了!!! 慢慢加油吧!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/473248.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【】lambda表达式

文章目录 lambda表达式lambda概念lambda表达式的格式关于捕获列表常见问题: 使用lambda表达式交换两个数lambda表达式底层原理 lambda表达式 lambda概念 lambda表达式本质是一个匿名函数(因为它没有名字),恰当使用lambda表达式可以让代码变得简洁.并且可以提高代码的可读性 例…

字节后端入门 - Go 语言原理与实践

1.1什么是Go语言 1.2Go语言入门 环境 1.3基础语法 1.3.1变量 var name"value" 自己推断变量类型&#xff1b; 也可以显式类型 var c int 1 name: type(value) 常量&#xff1a; const name "value" g : a"foo" 字符串拼接 1.3.2 if else {}花括号…

Java——多线程和锁

多线程 前言:当我们打开一个网站时&#xff0c;不同部分的加载并不是先后出现的&#xff0c;是并行出现的&#xff0c;没有出现一个地方没加载完&#xff0c;别的地方就也加载不出来这种事。这个就是多线程并行运行。 当其中一个线程发生阻塞时&#xff0c;操作系统会自动执行…

系统集成项目管理工程师 笔记(第12章:项目沟通管理和干系人管理)

文章目录 12.1.2 沟通的方式 404沟通管理计划的编制过程12.2.2 制订沟通管理计划的工具 4114、沟通方法 12.3.2 管理沟通的工具 41312.4.2 控制沟通的技术和方法 4163、会议 12.5.1 项目干系人管理所涉及的过程 420项目干系人管理的具体内容&#xff1a;&#xff08;1&#xff…

C/C++文件操作/IO流

学习任务&#xff1a; ⭐认识文件。⭐学习C语言中文件如何打开和关闭。⭐学习C语言中文件的读写方法&#xff08;包括顺序读写和随机读写&#xff09;。⭐学习C语言文件操作中如何判断文件读取结束。⭐简单了解FILE缓冲区。⭐认识流。⭐学习C的IO流&#xff0c;包括标准IO流和文…

【CMake】给一个库添加用法需求(Usage Requirements)

3. 给一个库添加用法需求&#xff08;Usage Requirements&#xff09; 1. usage requirements 目标参数的用法要求&#xff08;不知道有没有更好的翻译方式&#xff09;可以更好地控制库或可执行的链接&#xff0c;并包括行&#xff0c;同时还可以更好地控制CMAKE内部目标的传…

【哈士奇赠书活动 - 17期】-〖uni-app跨平台开发与应用从入门到实践〗

文章目录 ❤️‍&#x1f525; 赠书活动 - 《uni-app跨平台开发与应用从入门到实践》❤️‍&#x1f525; 编辑推荐❤️‍&#x1f525; 抽奖方式与截止时间❤️‍&#x1f525; 赠书活动 → 获奖名单 ❤️‍&#x1f525; 赠书活动 - 《uni-app跨平台开发与应用从入门到实践》…

日志技术-Logback

一. 日志是什么&#xff1a; 输出语句的弊端&#xff1a;它只能在控制台展示&#xff0c;它不能记录在本地文件当中。 日志可以将程序运行过程中的信息直接记录在文件里面&#xff0c;做永久存储。 性能较好&#xff0c;简单来说就是运行的速度会比较快。 二. 日志技术体系、L…

3_docker应用部署:MySQL-Tomcat-Nginx-Redis

Docker 应用部署 一、部署MySQL 案例需求&#xff1a;在Docker容器中部署MySQL&#xff0c;并通过外部mysql客户端操作MySQL Server。 分析&#xff1a; 容器内的网络服务和外部机器不能直接通信 外部机器和宿主机可以直接通信 宿主机和容器可以直接通信 当容器中的网络服…

iOS 17 开放侧载,微信双开要来了?

关于苹果北京时间 6 月 6 日召开的 WWDC23 全球开发者大会&#xff0c;外媒彭博记者 Mark Gurman 带来了最新消息。 大致更新概览 他认为&#xff0c;本次 WWDC23 大会将会主要推出这几款产品和软件&#xff1a;iOS 17、iPadOS 17、macOS 14、watchOS 10、新的 MacBooks 、混…

文件上传下载系列——如何实现文件秒传

文章目录 &#x1f383;简介&#xff1a; &#x1f47b;核心思想&#xff1a; MD5是什么&#xff1f; 实现步骤&#xff1a; &#x1f384;实操&#xff1a; 1、java生成文件MD5码 2、javascript生成文件MD5码 ⛳️基于秒传的分片上传下载 上传&#xff1a; 下载&…

Afkayas.1(★)

软件运行 要输入正确的Name和Serial 查壳 一个VB程序&#xff0c;没有加壳 载入OD 直接开搜索字符串。 这里看到了错误的提示&#xff0c;“You Get It”应该就是成功的字符串了。 前面的“AKA-”应该是在什么时候拼接的字符串 去成功的字符串附近看看 这个字符串上面…

LVS负载均衡群集——DR模式

一、LVS-DR集群介绍 LVS-DR&#xff08;Linux Virtual Server Director Server&#xff09;工作模式&#xff0c;是生产环境中最常用的一 种工作模式。 1、LVS-DR 工作原理 LVS-DR 模式&#xff0c;Director Server 作为群集的访问入口&#xff0c;不作为网关使用&#xff0…

第九章 子查询

文章目录 前言一、.需求分析与问题解决1 、实际问题2 、子查询的基本使用3 、子查询的分类 二、单行子查询1、单行比较操作符2、代码示例3、 HAVING 中的子查询4、CASE中的子查询5、 子查询中的空值问题6、非法使用子查询 三、多行子查询1、 多行比较操作符2、代码示例3 、空值…

客快物流大数据项目(一百一十八):配置中心 Spring Cloud Config

文章目录 配置中心 Spring Cloud Config 一、​​​​​​​Config 简介

STM32-HAL-SPI-W25Q128FV简单读写测试(2)

文章目录 一、Flash的基本读写操作1.1 向芯片中的某个地址&#xff08;addr:0x02&#xff09;连续写入不定长的数据并读取代码示例读写流程分析函数分析 1.2 向芯片中的某个地址&#xff08;addr:0x00&#xff09;写入一个数值代码示例&#xff1a;读写流程分析 具体的配置接上…

react native ios 添加启动页 xcode14

最近更新xcode&#xff0c;有些配置有些不同&#xff0c;网上查的方法都是过时的&#xff0c;导致配了一段时间卡在这里&#xff0c;最后访问官网才弄好了&#xff0c;所以以后解决问题的办法先看官网再查其他各路神仙的办法。 官网的步骤&#xff1a;https://github.com/crazy…

MAC 查看已装载的卷宗

查看卷宗目录命令 ls /Volumes网络卷宗&#xff1a;本机、系统报告。 参考资料&#xff1a;https://blog.csdn.net/qq_41731201/article/details/125407204

建筑行业如何进行高效管理文件?

建筑设计行业在日常办公中会产出大量文件&#xff0c;如设计图纸协作商议&#xff0c;项目资料等&#xff0c;建筑行业该如何高效管理文件呢&#xff1f; 建筑设计行业团队可能遇到的文件管理问题&#xff1a; 1&#xff0c;设计图纸一般较大&#xff0c;来回传输不仅麻烦&…

【矩阵快速幂 | 斐波那契数列 | 矩阵加速】

文章目录 基础知识1. 矩阵结构2. 重载 * 运算符3. 矩阵快速幂 例题1&#xff1a; 矩阵幂求和例题2&#xff1a; 矩阵快速幂例题3&#xff1a; 斐波那契数列例题4&#xff1a; 矩阵加速例题5&#xff1a; 广义斐波那契例题6&#xff1a; 斐波那契公约数例题7&#xff1a; 这个勇…