题目地址: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. pytest中文文档

    在网上找到的感觉还不错的pytest的中文文档,这里收藏一下: 翻译的中文文档:完整的Pytest文档 中文文档链接地址: https://www.osgeo.cn/pytest/contents.h ...

  2. 深入理解 PHP 高性能框架 Workerman 守护进程原理

    大家好,我是码农先森. 守护进程顾名思义就是能够在后台一直运行的进程,不会霸占用户的会话终端,脱离了终端的控制.相信朋友们对这东西都不陌生了吧?如果连这个概念都还不能理解的话,建议回炉重造多看看 Li ...

  3. 牛客周赛 Round 5

    牛客周赛 Round 5 A-游游的字母变换_牛客周赛 Round 5 (nowcoder.com) #include <bits/stdc++.h> #define int long l ...

  4. JavaScript设计模式样例二十一 —— 解释器模式

    解释器模式(Interpreter Pattern) 定义:提供了评估语言的语法或表达式的方式.目的:对于一些固定文法构建一个解释句子的解释器.场景:编译器.运算表达式计算. // 定义对于语法的断言 ...

  5. liunx下安装Nginx

    Linux下nginx的安装以及环境配置 https://blog.csdn.net/qq_42815754/article/details/82980326 第一步:下载nginx压缩包 在这里可以 ...

  6. SSM_Spring+SpringMVC+MyBatis学习

    没听过的重点部分 springSecurity 4.0开始默认打开_csrf防护,但是会导致403 forbidden问题,所以可以关闭,但是关了就没有csrf防护了 其中还有传递的token和加密的 ...

  7. CANopen学习笔记(三)NMT

    NMT NMT主要用来管理和控制各个节点的状态,具体协议可以分为以下四类: NMT protocol Node guard protocol Heartbeat protocol Bootup pro ...

  8. 工程化Vue使用

    目录 环境准备 Vue项目-创建 Vue项目开发流程 API风格 案例 推荐阅读: VUE-局部使用 环境准备 介绍:create-vue是Vue官方提供的最新的脚手架工具,用于快速生成一个工程化的V ...

  9. 深入理解JavaScript中的try catch finally

    在日常开发中,我们经常使用try catch 来捕捉错误,来提升应用程序的健壮性,但是,大部分时候,只是惯性使用,很少静下来去深入理解一下try catch finally,所以本文将对try cat ...

  10. JavaScript – ES Module

    前言 关于 JavaScript Modular 的多种版本和历史看这篇. 参考: 阮一峰 – Module 的语法 阮一峰 – Module 的加载实现 Export 语法 逐个 export 在想 ...