自守數是指某個數的平方的末尾幾位數等於這個數的數。
基本介紹
- 中文名:自守數
- 代表數字:5
- 其他名詞:平凡自守數
- 意思:某數平方末尾幾位數等這個數的數
簡介,編程計算,JAVA,c++的實現,matlab 數值計算軟體實現,
簡介
定義:自然數n稱為p-進制下的自守數若且唯若 n(n-1)能被p^m整除其中m=1+[log_p n]。取p=10時即為此自守數的定義。
0和1的平方的個位數仍然是0和1(對任何p進制),稱為平凡自守數。
注意:當p為素數時,只有平凡自守數。
顯然,5和6是一位自守數(5x5=25 6x6=36)
25x25=625 76x76=5776,所以25和76是兩位自守數。
自守數有一個特性,以他為後幾位的兩個數相乘,乘積的後幾位仍是這個自守數。因為5時自守數,所以以5為個位數的兩個數相乘,乘積的個位仍然是5;76是自守數,所以以76為後兩位數的兩個數相乘,其結果的後兩位仍是76,如176x576=101376。
三位自守數是625和376,四位自守數是0625和9376,五位自守數是90625和09376......
我們可以看到,(n+1)位的自守數出自n位的自守數。由此得出,如果知道n位的自守數a,那么(n+1)位的自守數應當由a前面加上一個數構成。(僅對p的素因子個數為2時適用)
實際上,簡化一下,還能發現如下規律:
5+6=11
25+76=101
625+376=1001
......
定理(自守數的對稱性):設n為非平凡自守數,m為最小的使得p^m>n的數,則s=p^m+1-n是自守數
證明:觀察易發現,因為n>1,則p^m>s,我們取模p^m的同餘,有(p^m-n)(p^m+1-n) = (-n)(1-n)=n(n-1)=0,最後一個同餘號成立是因為n為自守數
註記:其實對於平凡情形,這個定理也成立,如0是自守數,則1-0=1也是自守數。
定理(沒有給出證明,歡迎補充):設p的不同的素因子個數為n,則大於p^m小於p^(m+1)的自守數的個數為2^n-2個
推論,p=10時,n位數的自守數有且只有兩個,二者它們的和等於10^n+1
所以,兩個n位自守數,他們的和等於10^n+1
編程計算
JAVA
實現:
public class ZishouNumber {
public static void main(String[] args) {
for(int i = 1; i < 10000; i++){
String strI = String.valueOf(i);
String multiStr = String.valueOf(i*i);
String last = multiStr.substring(multiStr.length() - strI.length());
if(last.equals(strI)){
System.out.println(i + "*" + i + "=" + multiStr + "--> " + i + " is Zishoushu");
}
}
}
}
--------------------------
1*1=1--> 1 is Zishoushu
5*5=25--> 5 is Zishoushu
6*6=36--> 6 is Zishoushu
25*25=625--> 25 is Zishoushu
76*76=5776--> 76 is Zishoushu
376*376=141376--> 376 is Zishoushu
625*625=390625--> 625 is Zishoushu
9376*9376=87909376--> 9376 is Zishoushu
c++的實現
#include<iostream.h>
class Self
{
private:
int a[20];
int m,n,p;
public:
Self(int _m,int _n)
{
m=_m;n=_n;
}
void process()
{
int pf;
int j=0;
p=0;
for(int i=m;i<=n;i++)
{
int k=i;
pf=k*k;
while(k!=0)
{
if((pf%10)!=(k%10))break;
k=k/10;
pf=pf/10;
}
if(k==0)
{
a[j]=i;
p++;
j++;
}
}
}
void print()
{
cout<<"自守數的個數為:"<<p<<endl;
for(int j=0;j<p;j++)
cout<<a[j]<<'\t';
cout<<endl;
}
};
void main()
{
Self test(1,110);
test.process();
test.print();
}
matlab 數值計算軟體實現
tic;
clear all
clc
j=0;
date=zeros(1,100);
for i=0:500000000
n=1+floor(log10(i));
if i==mod(i^2,10^n)
j=j+1;
date(j)=i;
end
end
%clear i j n
answer = date(1:j)
toc