本题要求实现一个函数,判断任一给定整数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
🤔思路:
本题所写函数要满足的两个条件:
-
是完全平方数
-
有两位数字相同
完全平方数判断:一个数完全平方数满足这个数是一个正整数,而且一个正整数的平方等于这个数,所以切入点就是要判断的正整数不存在一个正整数的平方等于它本身则概该数不是完全平方数。我们知道函数sqrt(n)返回根号n,若n不能完全平方则sqrt(n)返回的值是一个小数,所以对sqrt(n)强制转换为int型之后,(int)(sqrt(n))<sqrt(n),所以只要(int)(sqrt(n))*(int)(sqrt(n))!=N 则该数就不是完全平方数
至少有两位数字相同判断:我们第一想法往往就是将目标进行拆解,统计各个数的出现次数,但相对蛮烦。这里提供一个比较快速方便的解法,这种方法类似于之前学过过的哈希表。我们知道组成一个数的元素是0 ~ 9这十个数字,所以我们定义一个空间大小为10的数组a[10],并将数组元素a[0]~a[10]初值都设置为0,依次遍历目标数各个位上的数字,将 a[目标数] 置1,若再次遍历到相同的数字时,此时 a[目标数] 在上次就已经置为1了,所以在这就可以给出有两个数相同的结论。
完整代码如下:
int IsTheNumber ( const int N )
{
int a[10] = {0};
int d;
int n = N;
if((int)(sqrt(n))*(int)(sqrt(n))==N){
while(1){
d = n%10;
if(a[d])
return 1;
a[d] = 1;
n /= 10;
if(n == 0) return 0;
}
}
else{
return 0;
}
}