C语言趣味问题系列【2】自守数

1. 问题描述

什么是自守数
如果一个数字的平方的尾数刚好等于该数本身,那么这个数就是自守数。
例如:
5 * 5 = 2525 * 25 = 62576 * 76 = 5776

本文要求出0~1000以内的自守数。

2. 问题分析

首先分析平方后结果的构成,以376为例:
376 * 376 = 141376
① 376 * 6 = 2256
② 376 * 70 = 26320
③ 376 * 300 = 112800
141376 = ① + ② + ③

虽然数字很大,但是对自守数的判读有用的其实只有①②③中数字的最后三位之和的最后三位:256 + 320 + 800 = 1376

因此判定一个数num是否为自守数的步骤如下:
1)计算数字num是几位数字,把位数存储在n里;
2)被乘数num依次乘上num的各个位上的数字,求出前文中的①②③。
3)提取①②③的最后n位数值,并依次相加,得到res;
4)提取res的最后n位数值,与num相比,如果二者相等,那么num就是自守数。

3. 代码

#include <stdio.h>
int zishou(int num);   //判断自守数的子程序,返回长度为n的数的平方值的最后n位
int len(int num);   //计算任意一个int类型数的长度

void main()
{
	int i, count=0;   //count表示这是0-1000的第几个自守数
	
	for(i=0;i<=1000;i++)
	{
		if(zishou(i)==i)   //是自守数
		{
			printf("第%d个自守数: i=%d i*i=%d\n", ++count, i, i*i);
		}
	}
}

//计算任意一个int类型数的长度
int len(int num)
{
	int len;
	
	for(len=0;num!=0;len++)
	{
		num/=10;
	}
	
	return len;
}

//判断自守数的子程序,返回长度为n的数的平方值的最后n位
int zishou(int num)
{
	int res=0;
	int cpy;
	int i, exp=1;
	int k=1;
	
	cpy = num;   //cpy是被乘数,num原始值之后会因为位数提取而被改变,所以要备份
	for(i=0;i<len(cpy);i++)
	{
		exp *= 10;
	} 

	//依次提取① ② ③(详见问题分析部分)中的最后n位的数值(判断对象有n位,例如对于判断对象376, n=3),求出他们的值,存储在res里
	while(num!=0)
	{
		res += (cpy*(num%10)*k)%exp;
		num /= 10;
		k *= 10;
	}
	
	//提取res的最后n位
	return res%exp;
}

结果展示:
结果

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值