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才对。


总结

未完待续

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

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

相关文章

代码随想录算法训练营:23/60

非科班学习算法day23 | LeetCode39:组合总和 &#xff0c;Leetcode40:组合总和|| 介绍 包含LC的两道题目&#xff0c;还有相应概念的补充。 相关图解和更多版本&#xff1a; 代码随想录 (programmercarl.com)https://programmercarl.com/#%E6%9C%AC%E7%AB%99%E8%83%8C%E6%9…

计算机的错误计算(二十五)

摘要 介绍&#xff08;不&#xff09;停机问题。给了一个算式&#xff0c;当计算机的输出为0时&#xff0c;一般需要提高计算精度继续计算&#xff0c;一直到获得非0值或有效数字。但是&#xff0c;由于事先不清楚算式的准确值是否为0或不为0&#xff0c;因此往往陷入两难境地…

java包装类。

包装类介绍 Java的包装类&#xff08;Wrapper Classes&#xff09;是Java语言为八种基本数据类型&#xff08;byte, short, int, long, float, double, char, boolean&#xff09;提供的对应类。这些包装类允许我们将基本数据类型当作对象来处理&#xff0c;并提供了许多有用的…

常见的网络协议在不同的模型中层次分布

常见的网络协议根据其功能和作用&#xff0c;分布在OSI七层参考模型或TCP/IP四层参考模型的不同层次中。以下是这些协议在不同模型中的层次分布&#xff1a; 在OSI七层参考模型中的层次分布 物理层&#xff1a; 这一层主要涉及物理连接的建立和物理信号的传输&#xff0c;但通…

【Java15】继承

继承是面向对象三大特征之一&#xff0c;也是软件代码服用的重要手段。 Java只允许单继承&#xff0c;即每个子类只有一个直接父类。 C中的多继承被Java舍弃了&#xff0c;原因是多继承一方面难以准确表述类之间的关系&#xff0c;另一方面很容易造成代码错误。总结起来就两个…

双系统ubuntu20.04扩容

windows端 打开磁盘管理器&#xff0c;选择需要的盘点击压缩卷 点击未分配的盘&#xff0c;新建简单卷&#xff0c;一致点击下一步即可&#xff0c;记住分配的大小容量 ubuntu端 lsblk 查看所有的磁盘&#xff0c;可以看到新增为nvme0n1p4、nvme1n1p2 win分配的格式为NTFS&a…

【Excel】 批量跳转图片

目录标题 1. CtrlA全选图片 → 右键 → 大小和属性2. 取消 锁定纵横比 → 跳转高度宽度 → 关闭窗口3. 最后一图拉到最后一单元格 → Alt吸附边框![](https://i-blog.csdnimg.cn/direct/d56ac1f41af54d54bb8c68339b558dd1.png)4. CtrlA全选图片 → 对齐 → 左对齐 → 纵向分布!…

全网最适合入门的面向对象编程教程:11 类和对象的Python实现-子类调用父类方法-模拟串口传感器和主机

全网最适合入门的面向对象编程教程&#xff1a;11 类和对象的 Python 实现-子类调用父类方法-模拟串口传感器和主机 摘要&#xff1a; 本节课&#xff0c;我们主要讲解了在 Python 类的继承中子类如何进行初始化、调用父类的属性和方法&#xff0c;同时讲解了模拟串口传感器和…

OpenHarmony 入门——单元测试UnitTest快速入门

引言 OpenHarmony 的单元测试&#xff08;UnitTest&#xff09;是一个关键的软件开发过程&#xff0c;它确保代码的各个部分能够按预期工作&#xff0c;OpenHarmony的测试框架中提供了很多种的单元测试&#xff0c;今天简单介绍下UnitTest 类型的TDD测试。 OpenHarmony 的TDD …

Nacos 国际化

项目需要&#xff0c;后端异常信息需要进行国际化处理。所有想有没有方便易用的可选项。 1、国际化配置调整&#xff0c;不需要重启系统 2、可支持添加不同或自定义语言包&#xff08;就是配置的资源文件&#xff09; 参考&#xff1a; Nacos实现SpringBoot国际化的增强_spr…

Android IP地址、子网掩码、默认网关、首选DNS服务器、备用DNS服务器校验

Android IP地址、子网掩码、默认网关、首选DNS服务器、备用DNS服务器校验 public String isIP(String ip) {String regex = "(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]?\\d)){3}";Pattern p = Pattern.compile(regex)

LeetCode热题100刷题9:25. K 个一组翻转链表、101. 对称二叉树、543. 二叉树的直径、102. 二叉树的层序遍历

25. K 个一组翻转链表 /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x), next(nullptr) {}* ListNode(int x, ListNode *next) : val(x), nex…

uni-app + vue3项目引入unocss

使用方法&#xff1a;unocss 版本最好使用0.58&#xff0c;版本太高的话不兼容引入时会报错 在class中使用&#xff0c;如&#xff1a;class"w-full"

华为机考前准备工作

很多同学在刷完真题后&#xff0c;就直接去考试了&#xff0c;会发现不是卡在了题目的难度上&#xff0c;而是卡在了代码数据的如何输入上。为了避免各位有志之士忽略小细节而导致的前功尽弃&#xff0c;博主特意总结了华为机考试题数据输入的几种情况及其源代码&#xff0c;仅…

go语言day12 包 init() time包 file包

包 包中的 结构体 及结构体属性 方法 都可以通过设置首字母大小写来实现权限访问&#xff0c;首字母大写任何包中都可以访问&#xff0c;首字母小写只在同包中可以访问。 再导入包go文件时&#xff0c;可以给.go文件取别名。 在导入的包名前加入 _ 意思是调用该包的初始…

普中51单片机:矩阵按键扫描与应用详解(五)

文章目录 引言电路图开发板IO连接矩阵键盘的工作原理行列扫描逐行/逐列扫描 LCD1602代码库代码演示——暴力扫描代码演示——数码管(行列式)代码演示——线翻转法代码演示——LCD1602密码锁 引言 矩阵按键是一种通过行列交叉连接的按键阵列&#xff0c;可以有效地减少单片机I/…

AI学习指南机器学习篇-K均值聚类模型应用与Python实践

AI学习指南机器学习篇-K均值聚类模型应用与Python实践 1. 介绍 在机器学习领域&#xff0c;聚类算法是一种常用的无监督学习方法&#xff0c;其中K均值聚类是其中一种经典算法。K均值聚类算法通过将样本分配到K个不同的簇中&#xff0c;使得簇内的样本相似度最大&#xff0c;…

计算机网络 - 万字长文

计算机网络 二、计算机网络2.1 七层模型表格2.2 通俗讲解七层模型2.3 TCP与UDP对比2.4 TCP 三次握手过程==为什么握手是三次,而不是两次或者四次?====三次握手可以携带数据吗?====TCP三次握手失败,服务端会如何处理?====什么是半连接队列?全连接====ISN(Initial Sequence…

基于单片机的太阳能热水器控制系统设计

随着我国经济水平的不断提高&#xff0c;民众对生活质量的追求也在不断进步&#xff0c;对于现代家庭而言&#xff0c;热水器成为了必备的生活电器。目前市面上的电器主要是电热水器、燃气热水器以及太阳能热水器。就能源节约性能而言&#xff0c;太阳能热水器占据了绝对优势&a…

Java | Leetcode Java题解之第223题矩形面积

题目&#xff1a; 题解&#xff1a; class Solution {public int computeArea(int ax1, int ay1, int ax2, int ay2, int bx1, int by1, int bx2, int by2) {int area1 (ax2 - ax1) * (ay2 - ay1), area2 (bx2 - bx1) * (by2 - by1);int overlapWidth Math.min(ax2, bx2) -…