题目地址: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. 朋友吐槽我为什么这么傻不在源生成器中用string.GetHashCode, 而要用一个不够优化的hash方法

    明明有更好的hash方法 有位朋友对我吐槽前几天我列举的在源生成器的生成db映射实体的优化点 提前生成部分 hashcode 进行比较 所示代码 public static void Generate ...

  2. RISC-V全志D1多媒体套件文章汇总

    提示 此开发板的任何问题都可以在我们的论坛交流讨论 https://forums.100ask.net/c/aw/d1/57 文章目录汇总 教程共计14章,下面是章节汇总: 第0章_RISC-V全志D ...

  3. JavaScript设计模式样例六 —— 抽象工厂模式

    抽象工厂模式(Abstract Factory Pattern) 定义:抽象工厂模式提供了一种方式,可以将一组具有同一主题的单独的工厂封装起来.或者说,是其他工厂的工厂.目的:提供一个创建一系列相关或 ...

  4. 卡农 -- HNOI2011 -- DP&组合

    卡农 -- \(HNOI2011\) $$luogu$$ $$HZOI$$ 题意 给定一个 集合 $ A= { 1 \le x \le n | x } $ , 求出其 \(m\) 个不相同的且不为空集 ...

  5. MacPorts 使用

    安装 安装苹果命令行开发工具: xcode-select --install 下载并打开 MacPorts 安装包. 使用 MacPorts 中的软件包称为 port. sudo port selfu ...

  6. 【FFmpeg】之Mac系统爬取所有M3U8视频下载方法

    前言 由于有的网站不允许下载视频,到了有效期就不能看了,但是我想以后反复看,怎么办呢? 前提准备 操作系统:Mac 浏览器:谷歌浏览器 抓取m3u8工具:猫爪 视频处理工具:ffmpeg 需要安装工具 ...

  7. Spark 知识

    Spark 学习 Spark(一): 基本架构及原理 https://www.cnblogs.com/xing901022/p/8260362.html https://www.cnblogs.com ...

  8. C#自定义控件—指示灯

    C#用户控件之指示灯 在体现通讯状态.运行状态等用一个靓眼的指示灯如何做? 思路(GDI) 外环用笔绘制(Pen),内圆用画刷(SolidBrush); 两个方法(用笔画圆,用画刷填充圆的内部): 绘 ...

  9. “RazorTagHelper”任务意外失败。解决方案

    严重性    代码    说明    项目    文件    行    禁止显示状态错误    MSB4018    "RazorTagHelper"任务意外失败.System.I ...

  10. CF228E 题解

    CF228E 题解 题目简述 给定一个 \(n\) 个点,\(m\) 条边的无向图,每条边都为 \(0\) 或 \(1\),可以进行若干次操作,与此点相连的所有点权值取反,求一种方案使得所有边都变为 ...