HJ41 称砝码
HJ41 称砝码
提示:文章
文章目录
- 前言
- 一、背景
- 二、
- 2.1
- 2.2
- 总结
前言
前期疑问:
本文目标:
一、背景
这个题目之前是没有做出来的,我把之前没做出来的代码也记录一下
二、
2.1 之前的代码
#include <stdio.h>int main() {int a, b;int num = 0;int array[20000] = {0};while (scanf("%d", &num) != EOF) { // 注意 while 处理多个 case// 64 位输出请用 printf("%lld") to int key[num];int value[num];int count = 0;for(int i = 0; i < num; i++){scanf("%d", &key[i]);}for(int i = 0; i < num; i++){scanf("%d", &value[i]);}for(int i = 0; i < num; i++){while(value[i]){int heigh = key[i] * value[i];array[heigh] = 1;value[i]--;}}for(int i = 0; i < 20000; i++){if(array[i] > 0){count++;}}printf("%d\n", count + 1);printf("%d ", 0);for(int i = 0; i < 20000; i++){if(array[i] > 0){printf("%d ", i);}}}return 0;
}
示例是没有通过的
自测输入 | 2 1 2 2 1 |
---|---|
预期输出 | 5 |
实际输出 | 3 0 1 2 |
2.2 今天编的代码
2024年6月20日12:28:44
#include <stdio.h>
#include <stdlib.h>
#include <string.h>int compare(const void* a, const void* b)
{return (int*)a - (int*)b;
}int main() {int count = 0;char countStr[3] = {'\0'};while (fgets(countStr, 3, stdin) != NULL) { // 注意 while 处理多个 case// 64 位输出请用 printf("%lld") to countStr[1] = '\0';count = atoi(&countStr[0]);int weight[count];memset(weight, 0, sizeof(weight));int num[count];memset(num, 0, sizeof(num));char weightStr[21];char numStr[21];int weightIndex = 0;int numIndex = 0;fgets(weightStr, 21, stdin);fgets(numStr, 21, stdin);int len = strlen(weightStr);weightStr[strlen(weightStr) - 1] = '\0';numStr[strlen(numStr) - 1] = '\0';char* p = strtok(weightStr, " ");while(p){weight[weightIndex++] = atoi(p);p = strtok(NULL, " ");}p = strtok(numStr, " ");while(p){num[numIndex++] = atoi(p);p = strtok(NULL, " ");}for(int i = 0; i < count; i++){//printf("weight:%d, num:%d\n", weight[i], num[i]);}int length = pow(count, 2);int resultArray[length + 3];memset(resultArray, 0, sizeof(int) * (length + 3));//int resultArrayIndex = 1; //把0算作一个重量,把单独的重量也算上int resultArrayIndex = 0; //把0算作一个重量,把单独的重量也算上for(int i = 0; i < count; i++){for(int j = 0; j < num[i]; j++){resultArray[resultArrayIndex++] = weight[i] * j; }}for(int i = 0; i < count; i++){for(int j = 0; j < count; j++){resultArray[resultArrayIndex++] = weight[i] + num[j];}}int tempArray[20001] = {0};for(int i = 0; i < resultArrayIndex; i++){tempArray[resultArray[i]]++;}int resultArrayCopy[length + 3];int resultArrayCopyIndex = 0;for(int i = 0; i < 20001; i++){if(tempArray[i] != 0){// printf("index:%d, %d\n", i, tempArray[i]);resultArrayCopy[resultArrayCopyIndex++] = i;}}printf("%d", resultArrayCopyIndex);}return 0;
}
示例有误
用例输入 | 2 74 185 3 1 |
---|---|
预期输出 | 8 |
实际输出 | 7 |
2.3 2024年7月5日10:55:33编写代码
2024年7月5日10:55:33
现在的问题就是卡在测试用例18/20,问题是:
请检查是否存在数组、列表等越界非法访问,内存非法访问等情况。
这个问题待解决。
这次我调试代码的时候将测试用例用googleTest创建了单元测试,下面是CLion上的测试用例代码:
Clion调试代码如下
#include "HJ41.h"//#define TEST_DEBUG
#define TEST_DEBUG_ARRAY_PRINTint calculateWeight(int *weight, int weightLen, int *num, int numLen)
{int array[20001] = {0};int hash[300001] = {0};hash[0] = 1;int arrayIndex = 1;for(int i = 1; i <= num[0]; i++){int tempWeight = weight[0] * i;if(hash[tempWeight] == 0){array[i] = tempWeight;arrayIndex++;}hash[array[i]]++;}for(int i = 1; i < numLen; i++){int tempArrayIndex = arrayIndex;for(int j = 1; j <= num[i]; j++){for(int k = 0; k < tempArrayIndex; k++){int tempWeight = j * weight[i] + array[k];if(tempWeight < 300000 && hash[tempWeight] == 0){hash[tempWeight]++;array[arrayIndex] = tempWeight;arrayIndex++;}}}}#ifdef TEST_DEBUG_ARRAY_PRINTfor(int i = 0; i < arrayIndex; i++){printf("array[%d]:%d ", i, array[i]);}#endifreturn arrayIndex;
}int calculateWeight2(int *weight, int weightLen, int *num, int numLen)
{int array[2000] = {0};int hash[2000] = {0};hash[0] = 1;int arrayIndex = 1;for(int i = 1; i <= num[0]; i++){int tempWeight = weight[0] * i;if(hash[tempWeight] == 0){array[i] = tempWeight;arrayIndex++;}hash[array[i]]++;}for(int i = 1; i < numLen; i++){int tempArrayIndex = arrayIndex;for(int j = 1; j <= num[i]; j++){for(int k = 0; k < tempArrayIndex; k++){int tempWeight = j * weight[i] + array[k];if(tempWeight < 2000 && hash[tempWeight] == 0){hash[tempWeight]++;array[arrayIndex] = tempWeight;arrayIndex++;}
#ifdef TEST_DEBUGstd::cout << "j: " << j << std::endl;std::cout << "tempWeight: " << tempWeight << std::endl;
#endif}}}
#ifdef TEST_DEBUG_ARRAY_PRINTfor(int i = 0; i < arrayIndex; i++){std::cout << "array[" << i << "]" << array[i] << " ";}
#endifreturn arrayIndex;
}
写的测试用例如下
#include <gtest/gtest.h> // googletest header file
#include <iostream>
#include "HJ41.h"class googleMyTest : public testing::Test
{
public:static void SetUpTestCase(){std::cout << "SetUpTestCase" << std::endl;}static void TearDownTestCase(){std::cout << "TearDownTestCase" << std::endl;}virtual void SetUp(){std::cout << "SetUp" << std::endl;}virtual void TearDown(){std::cout << "TearDown" << std::endl;}
};TEST_F(googleMyTest, my_test_f_1)
{int x = 1;EXPECT_EQ(x, 1);
}TEST_F(googleMyTest, HJ41_1)
{int count = 2;int weight[2] = {1, 2};int num[2] = {2, 1};int totalCount = calculateWeight(weight, count, num, count);EXPECT_EQ(totalCount, 5);
}TEST_F(googleMyTest, HJ41_2)
{int count = 2;int weight[2] = {74, 185};int num[2] = {3, 1};int totalCount = calculateWeight(weight, count, num, count);EXPECT_EQ(totalCount, 8);
}TEST_F(googleMyTest, HJ41_3)
{int count = 3;int weight[] = {108, 29, 185};int num[] = {5, 2, 1};int totalCount = calculateWeight(weight, count, num, count);EXPECT_EQ(totalCount, 36);
}/** 这一版之前一直过不了是因为少了这个语句* hash[tempWeight]++;*/
TEST_F(googleMyTest, HJ41_4)
{int count = 3;int weight[] = {10, 191, 103};int num[] = {6, 6, 5};int totalCount = calculateWeight(weight, count, num, count);EXPECT_EQ(totalCount, 254);
}/** 报错段错误*/
//7
//172 162 18 153 199 41 28
//1 1 3 5 1 4 1
TEST_F(googleMyTest, HJ41_5)
{int count = 7;int weight[] = {172, 162, 18, 153, 199, 41, 28};int num[] = {1, 1, 3, 5, 1, 4, 1};int totalCount = calculateWeight(weight, count, num, count);EXPECT_EQ(totalCount, 969);
}
/** 原因有两个,段错误是因为hash数组没有做保护,被识别出来了* 另一个是输入字符串长度不够 应该将21改成100,保证fgets(weightStr, 100, stdin);能够获取足够长度的字符串*//** 这个是因为weight值会大于2000,使用2000判断肯定出问题啊*/
//7
//58 18 139 163 57 167 178
//1 1 3 2 6 3 4
//1711
TEST_F(googleMyTest, HJ41_6)
{int count = 7;int weight[] = {58, 18, 139, 163, 57, 167, 178};int num[] = {1, 1, 3, 2, 6, 3, 4};int totalCount = calculateWeight(weight, count, num, count);EXPECT_EQ(totalCount, 1171);
}/** 这个问题更明显了,数量都达到2000+了,那肯定是array数组长度不够了*/
//10
//68 136 51 137 57 23 166 45 141 58
//3 4 6 6 4 6 2 2 1 3
TEST_F(googleMyTest, HJ41_7)
{int count = 10;int weight[] = {68, 136, 51, 137, 57, 23, 166, 45, 141, 58};int num[] = {3, 4, 6, 6, 4, 6, 2, 2, 1, 3};int totalCount = calculateWeight(weight, count, num, count);EXPECT_EQ(totalCount, 2738);
}
//但是数组array长度改成10000,还是报错:请检查是否存在数组、列表等越界非法访问,内存非法访问等情况
//cao,这个示例在clion上执行不会失败,网页又是失败,我还以为是数组越界,最后突然想到是不是因为fgets获取长度不够,一看果然是这样
//但是在牛客商还是有问题,定位出来是count获取也有问题,应该是10,获取到的是1, 把语句改成fgets(countStr, 4, stdin)//10
//2000 1999 1998 1997 1996 1995 1994 1993 1992 1991
//10 10 10 10 10 10 10 10 10 10
TEST_F(googleMyTest, HJ41_8)
{int count = 10;int weight[] = {2000, 1999, 1998, 1997, 1996, 1995, 1994, 1993, 1992, 1991};int num[] = {10, 10, 10, 10, 10, 10, 10, 10, 10, 10};int totalCount = calculateWeight(weight, count, num, count);EXPECT_EQ(totalCount, 16601);
}
//最大值为array[16600]:199550。开启的数组长度不够
//改成int array[20001] = {0};
// int hash[300001] = {0};//aced 通过全部用例
//运行时间
//2ms
//占用内存
//1708KB
工程cmakelist
cmake_minimum_required(VERSION 3.16.5)message("this is cmakelist log")
message(${CMAKE_CURRENT_SOURCE_DIR})get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME)
message(${ProjectId})
#set(ProjectId "Hello World!")
message(${ProjectId})
message(NAME)
string(REPLACE " " "_" ProjectId ${ProjectId})
message(${ProjectId})
project(${ProjectId} CXX)add_definitions(-DCHENGFAMA)
add_definitions(-DSTART_GOOGLETEST_MODULE)# 判断宏是否存在
if(DEFINED HELLOWORLD)message(STATUS "HELLOWORLD已定义")
else()message(STATUS "HELLOWORLD未定义")
endif()#添加宏定义Debug为CMAKE_BUILD_TYPE
SET(CMAKE_BUILD_TYPE "Debug")set(CMAKE_CXX_STANDARD 17)if (CMAKE_BUILD_TYPE STREQUAL Debug)set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -D_DEBUG")
else ()set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -D_DEBUG")
endif ()# 添加googletest库
add_subdirectory(googletest)#添加头文件
#例如:include_directories(/usr/include/abc /usr/include/xxx)
#是将“/usr/include/abc”和“/usr/include/xxx”这两个目录添加至编译器的头文件搜索目录(两个目录用空格分隔)。
include_directories(./include/)
include_directories(./HJ41)aux_source_directory(./src Src)
aux_source_directory(./gtest gtestSrc)
aux_source_directory(./HJ41 HJ41Src)#通过编译源文件来创建一个可执行文件,其中,name是生成的可执行文件的名称,source是创建可执行文件所需要的源文件。
#源文件可以使用aux_source_directory指令返回的变量(将源文件保存在这个变量中),也可以是指定的.cpp文件(注意路径)。
add_executable(${ProjectId}${Src}${gtestSrc}${HJ41Src}arraySort.cppmain.cpp)# 链接googletest库
target_link_libraries(${ProjectId} gtest_main)
我现在在想的是吗,如果使用STL就不会出现这个问题吗?
如果将array数组改成vector好像可以解决溢出的问题。
将hash改成,hash改不了吧?除非C++有封装好的hash。
这里突然意识到应该将araay数组改成set才对。
总结
未完待续
相关文章:
HJ41 称砝码
HJ41 称砝码 提示:文章 文章目录 前言一、背景二、 2.1 2.2 总结 前言 前期疑问: 本文目标: 一、背景 这个题目之前是没有做出来的,我把之前没做出来的代码也记录一下 二、 2.1 之前的代码 #include <stdio.h>int m…...

如何使用Python脚本实现SSH登录
调试IDE:PyCharm Python库:Paramiko 首先安装Paramiko包到PyCharm,具体步骤为:在打开的PyCharm工具中,选择顶部菜单栏中“File”下的“Settings”,在设置对话框中,选择“Project”下的“Proje…...

2024年文化研究与数字媒体国际会议 (CRDM 2024)
2024年文化研究与数字媒体国际会议 (CRDM 2024) 2024 International Conference on Cultural Research and Digital Media 【重要信息】 大会地点:珠海 大会官网:http://www.iccrdm.com 投稿邮箱:iccrdmsub-conf.com 【注意:稿将…...

14-52 剑和诗人26 - RAG 和 VectorDB 简介
检索增强生成 (RAG) 和 VectorDB 是自然语言处理 (NLP) 中的两个重要概念,它们正在突破 AI 系统所能实现的界限。 在这篇博文中,我将深入探讨 RAG,探索其工作原理、应用、优势和局限性。 我们还将研究 VectorDB,这是一种专用于向…...
如果MySQL出现 “Too many connections“ 错误,该如何解决?
当你想要连接MySQL时出现"Too many connections" 报错的情况下,该如何解决才能如愿以偿呢?都是哥们儿,就教你两招吧! 1.不想重启数据库的情况下 你可以尝试采取以下方法来解决: 增加连接数限制:…...
论文阅读:Rethinking Interpretability in the Era of Large Language Models
Rethinking Interpretability in the Era of Large Language Models 《Rethinking Interpretability in the Era of Large Language Models》由Chandan Singh、Jeevana Priya Inala、Michel Galley、Rich Caruana和Jianfeng Gao撰写,探讨了在大型语言模型ÿ…...
C++/Qt 信号槽机制详解
文章目录 C++/Qt 信号槽机制详解一、信号和槽的基本概念1. 信号2. 槽3. 连接二、信号和槽的基本使用1. 信号和槽的声明和定义2. 连接信号和槽三、信号和槽的工作原理1. MOC(Meta-Object Compiler)2. 事件循环3. 连接类型四、信号和槽的高级应用1. 自定义信号和槽2. Lambda 表…...
duplicate key value violates unique constraint
duplicate key value violates unique constraint 遇到的问题 你在尝试向数据库表 goods 插入新记录时,收到了 duplicate key value violates unique constraint 的错误。尽管你确认数据库中没有与尝试插入的 id 相同的记录,但错误依旧存在。进一步的调…...

YOLOv10改进 | EIoU、SIoU、WIoU、DIoU、FocusIoU等二十余种损失函数
一、本文介绍 这篇文章介绍了YOLOv10的重大改进,特别是在损失函数方面的创新。它不仅包括了多种IoU损失函数的改进和变体,如SIoU、WIoU、GIoU、DIoU、EIOU、CIoU,还融合了“Focus”思想,创造了一系列新的损失函数。这些组合形式的…...

docker nginx mysql redis
启动没有数据卷的nginx docker run -d -p 86:80 --name my-nginx nginx把/etc/nginx中的配置复制到宿主机 docker cp my-nginx:/etc/nginx /home/nginxlkl把/html 中的文件复制到宿主机 docker cp my-nginx:/etc/nginx /home/nginxlkl删除当前镜像 docker rm -f my-nginx重新起…...

Linux系统(CentOS)安装iptables防火墙
1,先检查是否安装了iptables 检查安装文件-执行命令:rpm -qa|grep iptables 检查安装文件-执行命令:service iptables status 2,如果安装了就卸装(iptables-1.4.21-35.el7.x86_64 是上面命令查出来的版本) 执行命令:…...
华为的服务器创新之路
华为作为全球领先的信息与通信技术解决方案供应商,其在服务器领域的创新方法不仅推动了企业自身的发展,也为整个行业的进步做出了重要贡献。以下是华为在服务器领域所采取的一些关键创新方法: 芯片级的自主创新 华为通过自主研发的“鲲鹏”处…...
对比service now和salesforce
目录 1. 核心功能和用途 2. 市场定位 3. 平台和扩展性 4. 用户界面和用户体验 5. 价格 总结 ServiceNow和Salesforce是两款广泛使用的企业软件平台,但它们的侧重点和用途有所不同。以下是对它们的详细比较: 1. 核心功能和用途 ServiceNow IT服务…...

树状数组
树状数组 树状数组的核心思想:分治。将数组以二叉树的形式进行维护区间之和。 设 a a a为原数组, t r e e tree tree为树状数组。 t r e e tree tree数组用于存储树上该结点下严格直连的子节点之和(例: t [ 1 ] a [ 1 ] , t [ 2 ] t [ 1 …...

【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第一篇 嵌入式Linux入门篇-
i.MX8MM处理器采用了先进的14LPCFinFET工艺,提供更快的速度和更高的电源效率;四核Cortex-A53,单核Cortex-M4,多达五个内核 ,主频高达1.8GHz,2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT…...

ansible常见问题配置好了密码还是报错
| FAILED! > { “msg”: “Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this. Please add this host’s fingerprint to your known_hosts file to manage this host.” } 怎么解决…...

python-课程满意度计算(赛氪OJ)
[题目描述] 某个班主任对学生们学习的的课程做了一个满意度调查,一共在班级内抽取了 N 个同学,对本学期的 M 种课程进行满意度调查。他想知道,有多少门课是被所有调查到的同学都喜欢的。输入格式: 第一行输入两个整数 N , M 。 接…...

6、Redis系统-数据结构-05-整数
五、整数集合(Intset) 整数集合是 Redis 中 Set 对象的底层实现之一。当一个 Set 对象只包含整数值元素,并且元素数量不大时,就会使用整数集合这个数据结构作为底层实现。整数集合通过紧凑的内存布局和升级机制,实现了…...

STM32学习历程(day5)
EXTI外部中断 中断 中断就是在主程序运行过程中 出现了特定的中断触发条件(中断源),CPU会暂停当前的程序,去处理中断程序 处理完会返回被暂停的位置 继续运行原来的程序。 中断优先级 当有多个中断源同时申请中断时 CPU会根据…...

格蠹汇编阅读理解
一、调试工具使用方式 WinDbg常用命令: 执行 lm 命令,可以看到进程中有几个模块。执行~命令列一下线程。用!heap 命令列一下堆。执行!address 命令可以列出用户态空间中的所有区域。搜索吧!就从当前进程用户态空间的较低地址开始搜…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)
概述 在 Swift 开发语言中,各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过,在涉及到多个子类派生于基类进行多态模拟的场景下,…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...
如何为服务器生成TLS证书
TLS(Transport Layer Security)证书是确保网络通信安全的重要手段,它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书,可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...

用机器学习破解新能源领域的“弃风”难题
音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...
Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?
Pod IP 的本质与特性 Pod IP 的定位 纯端点地址:Pod IP 是分配给 Pod 网络命名空间的真实 IP 地址(如 10.244.1.2)无特殊名称:在 Kubernetes 中,它通常被称为 “Pod IP” 或 “容器 IP”生命周期:与 Pod …...

抽象类和接口(全)
一、抽象类 1.概念:如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象,这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法,包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中,⼀个类如果被 abs…...

数据结构第5章:树和二叉树完全指南(自整理详细图文笔记)
名人说:莫道桑榆晚,为霞尚满天。——刘禹锡(刘梦得,诗豪) 原创笔记:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 上一篇:《数据结构第4章 数组和广义表》…...
命令行关闭Windows防火墙
命令行关闭Windows防火墙 引言一、防火墙:被低估的"智能安检员"二、优先尝试!90%问题无需关闭防火墙方案1:程序白名单(解决软件误拦截)方案2:开放特定端口(解决网游/开发端口不通)三、命令行极速关闭方案方法一:PowerShell(推荐Win10/11)方法二:CMD命令…...