题解 | #自守数#
自守数
http://www.nowcoder.com/practice/88ddd31618f04514ae3a689e83f3ab8e
自守数
描述
自守数是指一个数的平方的尾数等于该数自身的自然数。例如:25^2 = 625,76^2 = 5776,9376^2 = 87909376。请求出n(包括n)以内的自守数的个数。本题有多组输入数据
示例1
输入:5
2000
输出:3
8
说明:对于样例一,有0,1,5,这三个自守数
2000
输出:3
8
说明:对于样例一,有0,1,5,这三个自守数
方法一:
思路分析
本题读完后的直接的思路是给定一个数,先求解出它的位数或者叫长度,然后将其平方的后面对应位数求出,比较两者的大小,如果两者值相等,那么这个数是自守数,这也是根据自守数的定义直接计算的
图解
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
核心代码
#include <bits/stdc++.h> using namespace std; int get_length(int x); int get_tail(int x,int count_i); int main() { int n=0; while(cin>>n) { if(n==0) cout<<0<<endl; else if(n==1) cout<<2<<endl; else { int count=2; for(int i=2;i<=n;i++) { int count_i=get_length(i);//计算i的位数 int sq_i=i*i;//i的平方 if(count_i==get_length(sq_i)) continue;//如果i与i的平方长度相等,则直接判定不是自守数 int tail=get_tail(sq_i,count_i);//计算i的平方后面对应的几位数 if(i==tail) count++; } cout<<count<<endl; } } return 0; } int get_length(int x)//计算整数的长度/位数,例如25有两位 { int leng=0; while(x) { x/=10; leng++; } return leng; } int get_tail(int x,int count_i)//计算整数的后面几位数 { int tail=0; for(int i=0;i<count_i;i++) { int mod_i=x%10; x=x/10; tail+=mod_i*pow(10,i);//例如25*25=625,则计算625后面两位数=25 //cout<<i<<" "<<mod_i<<" "<<10^i<<" "<<tail<<endl; } return tail; }
复杂度分析
- 时间复杂度:该算法的时间主要在计算一个整数的长度以及整数平方的后面几位,因此总的时间复杂度为$O(n)$
- 空间复杂度:空间复杂度为$O(1)$
方法二
思路分析
方法一中有许多不必要的工作,例如求解一个整数的位数,其实只要直接比较整数与其平方,方法为:每次模10得到的余数是否相等,然后更新整数和整数的平方为模10得到的值,直到整数为0(整数必然要比其平方数小)
核心代码
#include <bits/stdc++.h> using namespace std; int Automorphic_number(int sq_i,int i); int main() { int n; while(cin>>n) { if(n==0) cout<<0<<endl; else if(n==1) cout<<2<<endl; else { int count=2; for(int i=2;i<=n;i++) { int sq_i=i*i; if(Automorphic_number(sq_i, i)==1) count++; } cout<<count<<endl; } } return 0; } int Automorphic_number(int sq_i,int i) { while(i)//只需判断i,因为i<sq_i { if(sq_i%10!=i%10) return 0; else { sq_i=sq_i/10; i=i/10; } } return 1; }
复杂度分析
- 时间复杂度:对于一个整数不断取模运算,直到整数为0,时间复杂度为$O(n)$
- 空间复杂度:空间复杂度为$O(1)$