题目地址: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. 线段树学习笔记(基础&进阶)(一) | P3372 【模板】线段树 1 题解

    什么是线段树 线段树是一棵二叉树,每个结点存储需维护的信息,一般用于处理区间最值.区间和等问题. 线段树的用处 对编号连续的一些点进行修改或者统计操作,修改和统计的复杂度都是 O(log n). 基础 ...

  2. (转)深度学习word2vec笔记之基础篇

    深度学习word2vec笔记之基础篇 声明: 1)该博文是多位博主以及多位文档资料的主人所无私奉献的论文资料整理的.具体引用的资料请看参考文献.具体的版本声明也参考原文献 2)本文仅供学术交流,非商用 ...

  3. 深度学习word2vec笔记之基础篇

    作者为falao_beiliu. 作者:杨超链接:http://www.zhihu.com/question/21661274/answer/19331979来源:知乎著作权归作者所有.商业转载请联系 ...

  4. [学习笔记] Numpy基础 系统学习

    [学习笔记] Numpy基础 上专业选修<数据分析程序设计>课程,老师串讲了Numpy基础,边听边用jupyter敲了下--理解+笔记. 老师讲的很全很系统,有些点没有记录,在PPT里就不 ...

  5. 从头开始学JavaScript 笔记(一)——基础中的基础

    原文:从头开始学JavaScript 笔记(一)--基础中的基础 概要:javascript的组成. 各个组成部分的作用 . 一.javascript的组成   javascript   ECMASc ...

  6. MyBatis:学习笔记(1)——基础知识

    MyBatis:学习笔记(1)--基础知识 引入MyBatis JDBC编程的问题及解决设想 ☐ 数据库连接使用时创建,不使用时就释放,频繁开启和关闭,造成数据库资源浪费,影响数据库性能. ☐ 使用数 ...

  7. bootstrap学习笔记之基础导航条 http://www.imooc.com/code/3111

    基础导航条 在Bootstrap框中,导航条和导航从外观上差别不是太多,但在实际使用中导航条要比导航复杂得多.我们先来看导航条中最基础的一个--基础导航条. 使用方法: 在制作一个基础导航条时,主要分 ...

  8. Django学习笔记(基础篇)

    Django学习笔记(基础篇):http://www.cnblogs.com/wupeiqi/articles/5237704.html

  9. ArcGIS案例学习笔记-聚类点的空间统计特征

    ArcGIS案例学习笔记-聚类点的空间统计特征 联系方式:谢老师,135-4855-4328,xiexiaokui@qq.com 目的:对于聚集点,根据分组字段case field,计算空间统计特征 ...

  10. C#学习笔记(基础知识回顾)之值类型与引用类型转换(装箱和拆箱)

    一:值类型和引用类型的含义参考前一篇文章 C#学习笔记(基础知识回顾)之值类型和引用类型 1.1,C#数据类型分为在栈上分配内存的值类型和在托管堆上分配内存的引用类型.如果int只不过是栈上的一个4字 ...

随机推荐

  1. Linux信号量(1)-SYSTEM V

    ​ 信号量概念 信号量本质上是一个计数器(不设置全局变量是因为进程间是相互独立的,而这不一定能看到,看到也不能保证++引用计数为原子操作),用于多进程对共享数据对象的读取,它和管道有所不同,它不以传送 ...

  2. 全志TinyVision芯片文章汇总

    全志TinyVision芯片 TinyVision开发交流QQ群:821628986 文章目录汇总 教程共计14章,下面是章节汇总: 第0章_TinyVision套件简述 第1章_源码工具文档手册 第 ...

  3. C# JSON序列化指定名称

    今天在做项目时遇到了要将json对象序列化为数据库表,  结果数据库表和json对象数据类型和字段名称对不上.于是就有了一下的解决方案: 需要转化的对象 { "orgAccountId&qu ...

  4. 我恨 gevent

    报错了一晚上,最后发现是 python 版本不对.3.11,3.12,3.8,3.10 试了个遍,最后 3.10 终于编译通过了‍ 还有这个 greenlet,每次都是它和 gevent 合着来恶心我 ...

  5. 【DVWA】安全测试工具之BurpSuite

    一.应用场景 二.安装软件 官网下载地址:https://portswigger.net/burp/releases 下载版本2021.7 注册机的 Github 项目地址:TrojanAZhen/B ...

  6. 西瓜杯 WP

    RE 一个西瓜切两半你一半我一半 有点谜语,文本给的是输出和key # Visit https://www.lddgo.net/string/pyc-compile-decompile for mor ...

  7. 效率跃升16倍!火山引擎ByteHouse助力销售数据平台复杂查询效率大幅提高

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群.   销售数据,是反映市场趋势.消费者行为以及产品表现的重要指标,也是企业做出精准决策的关键依据.因此,对销售数据 ...

  8. 用python编写web 界面可以用哪些库

    背景: 很多人熟悉python, 但不熟悉前端语言js, 为了项目快速落地,也不太想去专门学习 React/Angular/Vue这些框架,那么就会问一个问题,能不能用Python直接写出一个简单we ...

  9. pyinstaller 打包成 exe

    生成 spec 和可执行文件: pyinstaller --onefile your_file.py 如果需要修改生成的spec文件,则后续可以这样运行: pyinstaller -F your_fi ...

  10. 爬虫案例2-爬取视频的三种方式之一:requests篇(1)

    @ 目录 前言 爬虫步骤 确定网址,发送请求 获取响应数据 对响应数据进行解析 保存数据 完整源码 共勉 博客 前言 本文写了一个爬取视频的案例,使用requests库爬取了好看视频的视频,并进行保存 ...