草庐IT

【题解笔记】PTA基础6-7:统计某类完全平方

SomeBottle的博客园站 2023-03-28 原文

题目地址:https://pintia.cn/problem-sets/14/problems/739

前言

咱目前还只能说是个小白,写题解是为了后面自己能够回顾。如果有哪些写错的/能优化的地方,也请各位多指教。( •̀ ω •́ )

题目描述

本题要求实现一个函数,判断任一给定整数N是否满足条件:它是完全平方数,又至少有两位数字相同,如144、676等。

展开查看详情

函数接口定义

int IsTheNumber ( const int N );

其中N是用户传入的参数。如果N满足条件,则该函数必须返回1,否则返回0。

裁判测试程序样例

#include <stdio.h>
#include <math.h>

int IsTheNumber ( const int N );

int main()
{
    int n1, n2, i, cnt;
    
    scanf("%d %d", &n1, &n2);
    cnt = 0;
    for ( i=n1; i<=n2; i++ ) {
        if ( IsTheNumber(i) )
            cnt++;
    }
    printf("cnt = %d\n", cnt);

    return 0;
}

/* 你的代码将被嵌在这里 */

输入样例

105 500

输出样例

cnt = 6

限制

限制内容 限制条件
代码长度限制 16 KB
时间限制 400 ms
空间限制 64 MB

想法

注:完全平方数指的是一个可以由 某一个整数的平方 表达的数。

判断完全平方数

首先观察给出的裁判测试程序样例,发现程序在预处理部分引入了math.h,很明显,要判断完全平方数,我们得用到math.h头文件中声明的sqrt()(开平方根)函数:

double sqrt ( double arg );

该函数返回的是一个双精度浮点数,如果其小数部分为0,则说明该数是完全平方数。

这样想,其实将sqrt()函数的返回值转换为整型,将这个整型的平方和原数进行比较,就可以判断是否为完全平方数了:

int squareRoot = (int) sqrt(N);
if (squareRoot * squareRoot == N) {
    // N是完全平方数
}

我最开始用了种危险的写法

double squareRoot = sqrt(N);
if (squareRoot == (int) squareRoot) {
    // N是完全平方数
}

运行起来可能不会出问题,但实际上是有隐患的。这里的逻辑其实是在将整型浮点型在进行比较,而计算机中的浮点数储存是不精确的,不要这样写。

至少有两位数字相同

虽然题目中给出的样例数都是三位数,但是PTA吧,肯定不会这么容易就让我过,那我肯定要再上升一层进行思考。

我的想法是从最低位开始,用数组储存每一位的数字。而在每次迭代中,将当前位的数字与数组中的每一位进行比较,只要遇到相同的,就能保证至少有两位数字相同:

// 判断整数number中是否至少有两位数字相同
int HasTwoSameNum(const int number) {
    int quotient = number; // 商
    int remainder; // 余数
    int arrLen = 0;
    int arr[10]; // int型最多10位数字
    int i;
    while (quotient > 0) {
        remainder = quotient % 10; // 余数
        quotient = quotient / 10; // 商
        for (i = 0; i < arrLen; i++) {
            if (arr[i] == remainder)
                return 1;
        }
        arr[arrLen++] = remainder;
    }
    return 0;
}

为什么定义数组时将元素个数定为10呢?因为题目中处理的数据类型是整型。

目前来说,一般的计算机中一个整型int占用4个字节,即32位,而32位的整型在计算机储存时要用到31个二进制位来表示数值(最高位表示符号),因此int的取值范围是-2^312^31-1,即-21474836482147483647

很明显,题目关注的是十进制数,观察2147483648能发现,int型的整数在十进制下最多只有10位,所以我才将数组的元素个数定为10


关于提取整数的每一位数字这部分,实际上用取模和取整就可以实现。

上述代码中,quotient % 10能得到quotient的最低位数字;而quotient / 10能得到quotient除去最低位数字的整数,这个数值就是下一次迭代的quotient

迭代至quotient0时,就已经把原整数中的每一位数都取遍了。

题解代码

OJ端提交的代码:

int HasTwoSameNum(const int number) {
    int quotient = number; // 商
    int remainder; // 余数
    int arrLen = 0;
    int arr[10]; // int型最多10位数字
    int i;
    while (quotient > 0) {
        remainder = quotient % 10; // 余数
        quotient = quotient / 10; // 商
        for (i = 0; i < arrLen; i++) {
            if (arr[i] == remainder)
                return 1;
        }
        arr[arrLen++] = remainder;
    }
    return 0;
}

int IsTheNumber(const int N) {
    int squareRoot = (int) sqrt(N);
    // 如果平方根都不是,就没必要调用HasTwoSameNum了
    if (squareRoot * squareRoot == N && HasTwoSameNum(N))
        return 1;
    else
        return 0;
}

本地测试可用:

#include <stdio.h>
#include <math.h>

int IsTheNumber(const int N);

int HasTwoSameNum(const int number);

int main() {
    int number;
    printf("Input an integer: ");
    fflush(stdout);
    scanf("%d", &number);
    printf("IsTheNumber = %d\n", IsTheNumber(number));

    return 0;
}

int HasTwoSameNum(const int number) {
    int quotient = number; // 商
    int remainder; // 余数
    int arrLen = 0;
    int arr[10]; // int型最多10位数字
    int i;
    while (quotient > 0) {
        remainder = quotient % 10; // 余数
        quotient = quotient / 10; // 商
        for (i = 0; i < arrLen; i++) {
            if (arr[i] == remainder)
                return 1;
        }
        arr[arrLen++] = remainder;
    }
    return 0;
}

int IsTheNumber(const int N) {
    int squareRoot = (int) sqrt(N);
    // 如果平方根都不是,就没必要调用HasTwoSameNum了
    if (squareRoot * squareRoot == N && HasTwoSameNum(N))
        return 1;
    else
        return 0;
}

提交结果

有关【题解笔记】PTA基础6-7:统计某类完全平方的更多相关文章

  1. ruby - 完全离线安装RVM - 2

    我打算为ruby​​脚本创建一个安装程序,但我希望能够确保机器安装了RVM。有没有一种方法可以完全离线安装RVM并且不引人注目(通过不引人注目,就像创建一个可以做所有事情的脚本而不是要求用户向他们的bash_profile或bashrc添加一些东西)我不是要脚本本身,只是一个关于如何走这条路的快速指针(如果可能的话)。我们还研究了这个很有帮助的问题:RVM-isthereawayforsimpleofflineinstall?但有点误导,因为答案只向我们展示了如何离线在RVM中安装ruby。我们需要能够离线安装RVM本身,并查看脚本https://raw.github.com/wayn

  2. postman接口测试工具-基础使用教程 - 2

    1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,

  3. 软件测试基础 - 2

    Ⅰ软件测试基础一、软件测试基础理论1、软件测试的必要性所有的产品或者服务上线都需要测试2、测试的发展过程3、什么是软件测试找bug,发现缺陷4、测试的定义使用人工或自动的手段来运行或者测试某个系统的过程。目的在于检测它是否满足规定的需求。弄清预期结果和实际结果的差别。5、测试的目的以最小的人力、物力和时间找出软件中潜在的错误和缺陷6、测试的原则28原则:20%的主要功能要重点测(eg:支付宝的支付功能,其他功能都是次要的)80%的错误存在于20%的代码中7、测试标准8、测试的基本要求功能测试性能测试安全性测试兼容性测试易用性测试外观界面测试可靠性测试二、质量模型衡量一个优秀软件的维度①功能性功

  4. LC滤波器设计学习笔记(一)滤波电路入门 - 2

    目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称

  5. ES基础入门 - 2

    ES一、简介1、ElasticStackES技术栈:ElasticSearch:存数据+搜索;QL;Kibana:Web可视化平台,分析。LogStash:日志收集,Log4j:产生日志;log.info(xxx)。。。。使用场景:metrics:指标监控…2、基本概念Index(索引)动词:保存(插入)名词:类似MySQL数据库,给数据Type(类型)已废弃,以前类似MySQL的表现在用索引对数据分类Document(文档)真正要保存的一个JSON数据{name:"tcx"}二、入门实战{"name":"DESKTOP-1TSVGKG","cluster_name":"elasticsear

  6. ruby-on-rails - Ruby on Rails 3 中的类方法——我完全迷路了! - 2

    背景here.在上面的链接中,给出了以下示例:classauthor.id)endend除了这种语法对于像我这样的初学者来说很陌生——我一直认为类方法是用defself.my_class_method定义的——我在哪里可以找到关于类的文档RubyonRails中的方法?据我所知,类方法总是在类本身(MyClass.my_class_method)上调用,但如果R​​ails中的类方法是可链接的,似乎必须进行其他操作在这里!编辑:我想我通过对类方法的语法发表评论有点被骗了。我真的想问Rails如何使类方法可链接—我了解方法链接的工作原理,但不知道Rails如何允许您链接类方法而无需实际返

  7. ruby - 如何使用私钥加密完全加密 Ruby 中的数据? - 2

    首先,关于我们系统的一些信息,它基本上是建筑行业的电子招标解决方案。所以:列表项我们的系统有多家公司每个公司都有多个用户每家公司可以创建多个拍卖然后其他公司可以为可用的拍卖提交他们的出价。一个出价包含数百或数千个单独的项目,我们只需要加密这些记录的“价格”部分。我们面临的问题是,我们的大客户不希望我们知道投标价格,至少在投标过程中是这样,这是完全可以理解的。现在,我们只是通过对称加密对价格进行加密,因此即使价格在数据库中有效加密,他们担心的是我们拥有解密价格的key。因此,我们正在研究某种形式的公钥加密系统。以下是我们对解决方案的初步想法:当一家公司注册时,我们会使用OpenSSL为其

  8. ruby-on-rails - ruby 真的是一种完全面向对象的语言吗? - 2

    Ruby是完全面向对象的语言。在ruby​​中,一切都是对象,因此属于某个类。例如5属于Objectclass1.9.3p194:001>5.class=>Fixnum1.9.3p194:002>5.class.superclass=>Integer1.9.3p194:003>5.class.superclass.superclass=>Numeric1.9.3p194:005>5.class.superclass.superclass.superclass=>Object1.9.3p194:006>5.class.superclass.superclass.superclass.su

  9. 【网络】-- 网络基础 - 2

    (本文是网络的宏观的概念铺垫)目录计算机网络背景网络发展认识"协议"网络协议初识协议分层OSI七层模型TCP/IP五层(或四层)模型报头以太网碰撞路由器IP地址和MAC地址IP地址与MAC地址总结IP地址MAC地址计算机网络背景网络发展        是最开始先有的计算机,计算机后来因为多项技术的水平升高,逐渐的计算机变的小型化、高效化。后来因为计算机其本身的计算能力比较的快速:独立模式:计算机之间相互独立。    如:有三个人,每个人做的不同的事物,但是是需要协作的完成。    而这三个人所做的事是需要进行协作的,然而刚开始因为每一台计算机之间都是互相独立的。所以前面的人处理完了就需要将数据

  10. Unity Shader 学习笔记(5)Shader变体、Shader属性定义技巧、自定义材质面板 - 2

    写在之前Shader变体、Shader属性定义技巧、自定义材质面板,这三个知识点任何一个单拿出来都是一套知识体系,不能一概而论,本文章目的在于将学习和实际工作中遇见的问题进行总结,类似于网络笔记之用,方便后续回顾查看,如有以偏概全、不祥不尽之处,还望海涵。1、Shader变体先看一段代码......Properties{ [KeywordEnum(on,off)]USL_USE_COL("IsUseColorMixTex?",int)=0 [Toggle(IS_RED_ON)]_IsRed("IsRed?",int)=0}......//中间省略,后续会有完整代码 #pragmamulti_c

随机推荐