首页 > 试题广场 >

自守数

[编程题]自守数
  • 热度指数:157093 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
\hspace{15pt}自守数是指这样一个自然数 x,其平方的尾数等于自身。更具体的说,即 x^2 的末尾若干位恰好等于 x,例如:
\hspace{23pt}\bullet\, 25^2=625625 的末尾两位恰好是 25
\hspace{23pt}\bullet\, 76^2=57765776 的末尾两位恰好是 76
\hspace{23pt}\bullet\, 9\,376^2=87\,909\,37687\,909\,376 的末尾四位恰好是 9\,376
\hspace{15pt}现在,对于给定的 n,请统计 0n 之间的自守数个数。

输入描述:
\hspace{15pt}输入一个整数 n \left(1 \leqq n \leqq 10^4\right) 代表自守数的范围。


输出描述:
\hspace{15pt}输出一个整数,代表 0n 之间的自守数个数。
示例1

输入

25

输出

5

说明

\hspace{15pt}在这个样例中,0,1,5,6,25 是自守数。
//注释护体
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int how_much_bits(int n); //求十进制数字位数
char* get_each_bit_num(int num, char arr[]); //获取十进制数字每个位上的数字
int is_zishoushu(int num); //判断是否是自守数
int how_much_zishoushu(int num); //计数有多少个自守数

int main() {
    char weishu[10];
    int num = 0;
    int ret = 0;
    scanf("%d", &num);
    memset(weishu, '\0', sizeof(weishu));
    ret = how_much_zishoushu(num);
    printf("%d\n", ret);
    return 0;
}

int how_much_bits(int n){
    int bits=0;
    while(n){
        n /= 10;
        bits++;
    }
    return bits;
}
char* get_each_bit_num(int num, char arr[]) {
    int i = 0;
    while (num) {
        arr[i] = num % 10 +'0';
        num = num / 10;
        i++;
    }
    return arr;
}
int is_zishoushu(int num){
    int ret = 0;
    int weishu_num = how_much_bits(num); //得到输入的数字的位数
    int sqar = num * num; //输入的数字的平方数
    char arr_sqar[10]; //存储平方数 每个位上的数字 的数组
    char arr_num[10];  //存储输入的数字 每个位上的数字 的数组
    memset(arr_sqar, '\0', sizeof(arr_sqar));
    memset(arr_num, '\0', sizeof(arr_num));
    get_each_bit_num(sqar, arr_sqar); //得到平方数的各个位上的数字
    get_each_bit_num(num, arr_num);   //得到输入的数字的各个位上的数字
    for(int i=0; i<weishu_num; i++){
        if(arr_num[i] != arr_sqar[i]){
            ret = 1;
            break;
        }
    }
    return ret;
}
int how_much_zishoushu(int num){
    int cnt=0, mid_ret=0;
    for(int i=0; i<=num; i++){
        if(i == 0 || i == 1){
            cnt++; // 0和1直接累加,无需计算
        } else {
            mid_ret = is_zishoushu(i); //是返回0,不是返回非0
            if(mid_ret == 0)
                cnt++;
        }
    }
    return cnt;
}


发表于 2024-12-02 16:01:44 回复(0)
#include <stdio.h>
#include<math.h>
int justic(int num) {
    int temp = 0, n;
    int len = 0;
    int temp2 = num;
    while (temp2) {
        temp2 /= 10;
        len++;
    }
    temp = num*num;
    n=temp%(int)pow(10, len);
    if (n == num) {
        return 1;
    }else{
        return 0;
    }
}

int main() {
    int num, count = 0;
    scanf("%d", &num);
    if (num == 0) {
        printf("%d", 1);
    }
    else {
        for (int i = 0; i <= num; i++) {
            if (justic(i) == 1) {
                count++;
            }
        }
        printf("%d", count);
    }

    return 0;
}

发表于 2024-08-20 20:53:07 回复(0)
#include <stdio.h>
int isIt(int a)
{
    int b = a*a;
    if (a==0||a==1) {
        return 1;
    }
    else if (a < 10) {
        if ((b-a)%10 == 0) {
            return 1;
        }
        else {
            return 0;
        }
    }
    else if ((a>10)&&(a<100)) {
        if ((b-a)%100 == 0) {
            return 1;
        }
        else {
            return 0;
        }
    }
    else if(a>100&&a<1000){
        if ((b-a)%1000 == 0) {
            return 1;
        }
        else {
            return 0;
        }
    }
    else if(a>1000&&a<10000){
        if ((b-a)%10000 == 0) {
            return 1;
        }
        else {
            return 0;
        }
    }
    return 0;
}
int main() {
    int x;
    scanf("%d",&x);
    int count = 0;
    for (int i = 0; i <= x; i++) {
        if (isIt(i)) {
            count++;
        }
    }
    printf("%d", count);
    return 0;
}
发表于 2024-06-05 16:44:36 回复(0)
#include <stdio.h>

int main() {
    int n=0,weishu=1,temp=0,count=0;
    int pingfang=0;
    scanf("%d", &n);
    for(int i=0; i<=n; i++)
    {
        pingfang = (i * i);
        temp = i;
        while(temp>0){
            weishu*=10;
            temp /= 10;
        }
        if((pingfang%weishu) == i)
        count++;
        weishu = 1;
    }
    printf("%d", count);
}

发表于 2024-06-04 21:33:16 回复(0)
不使用任何库函数的解法
#include <stdio.h>

int main() {
    int n = 0;      //记录输入的数量
    int sqr = 0;    //存放当前数的平方
    char flag = 0;  //自守数的标志位
    int counter = 0;//记录自守数的个数
    int temp = 0;
    scanf("%d", &n);

    for (int i=1; i<=n; ++i)
    {
        temp = i;
        sqr = temp * temp;
        while (temp != 0) //0是自守数,但不用参与计算,最后加上即可
        {
            if (sqr%10 == temp%10) //从最后一位开始比较
            {
                temp /= 10;
                sqr /= 10;
                flag = 1;
            }
            else //一旦某一位不符合自守数的要求,则标志位清0并跳出循环
            {
                flag = 0;
                break;
            }
        }
        if (flag == 1) ++counter; //temp每一位数都匹配成功才是自守数
    }
    printf("%d", ++counter); //0也算,但没有参与计算中
    return 0;
}


发表于 2024-05-15 22:04:57 回复(0)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main() {
    unsigned int c = 0;
    unsigned long n = 0 , t ;
    char str0[10] = {'\0'}, str1[25] = {'\0'};
    int flag = 1;
    scanf("%ld",&n);
    for(int i = 0 ; i <= n ; i++){
        t = i * i;
        sprintf(str0, "%d",i);
        sprintf(str1, "%ld", t);
        int l = strlen(str1);
        for(int j = strlen(str0) ; j > 0 ; j--){
            if(str0[j - 1] != str1[l - 1]){
                flag = 0;
                break;
            }
            l--;
        }
        if(flag == 1){
            c++;
            //printf("%d %ld\n",i,t);
        }
        else    flag = 1; 
        memset(str0, '\0', 10);
        memset(str1, '\0', 25);
    }
    printf("%d",c);
    return 0;
}

发表于 2023-12-26 22:31:53 回复(0)
#include <stdio.h>

int main() {
    int n=0;
    while (scanf("%d", &n) != EOF) {
        int num = 0;
        int flag = 10;
        for(int i = 0;i<=n;i++)
        {
            if(i>flag)
            {
                flag *=10;
            }
            double mul = (double)((i*i)%flag);
            if((int)mul == i)
            {
                num++;
            }
        }
        printf("%d",num);
    }
    return 0;
}
发表于 2023-10-11 12:36:03 回复(0)
#include <stdio.h>
#include<math.h>
int tensum(int n) {
    if (n > 0) {
        int sum = 0;
        while (n) {
            sum++;
            n /= 10;
        }
        return sum;
    } else return 1;
}
int main() {
    int a, b = 0, i, n, k, c0 = 0;
    scanf("%d", &a);
    b = 0;
    for (i = 0; i <= a; i++) {

        if ((i * i - i ) % (int)pow(10,
                                    tensum(i)) == 0) c0++; // 一个数的平方减去这个数,模上pow(10, 这个数的位数),如果是0那这个数就是自守数
    }
    printf("%d\n",  c0);
    return 0;
}

发表于 2023-04-08 19:32:12 回复(0)
// 一个数的平方减去这个数,模上pow(10, 这个数的位数),如果是0那这个数就是自守数
// 比如 5 平方是25   25-5==20  20%10==0   
// 所以 5是自守数   5是一位数  pow(10, 1)==10
//
// 比如 25 平放是625  625-25==600   600%100==0
// 所以25是自守数   25是两位数 pow(10, 2)==100
#include<math.h>
// 计算位数的函数
int mmod(int n)
{
    int count = 0;
    // 0是一位数也是自守数 单独判断
    if (n == 0)
        return 1;

    while (n)
    {
        n /= 10;
        count++;
    }
    return count;
}
int main()
{
    int n = 81;
    scanf("%d", &n);
    int i = 0;
    int num = 0;
    int dev = 10;
    for (i = 0; i <= n; i++)
    {
        // 每次循环重置
        dev = 10;
        int ret = mmod(i);
        // 模上dev
        dev = (int)pow(dev, ret);
        // 自守数判断
        if (((int)pow(i, 2) - i) % dev == 0)
        {
            //printf("%d ", i);
            num++;
        }
    }
    printf("%d\n", num);
    return 0;
}

发表于 2022-07-27 14:32:03 回复(0)
//走了弯路但能跑通
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
    int n;
    int cnt= 0,i=0;
    char str1[33] ={'\0'};
    char str2[33] ={'\0'};
    int len1 = 0,len2 = 0;
    while(scanf("%d",&n)!=EOF)
    {
        cnt = 0;
        for(i=0;i <=n;i++)
        {
             sprintf(str1,"%d",(i*i));
             sprintf(str2,"%d",i);
             len1 = strlen(str1);
             len2 = strlen(str2);
             if(strcmp(str1+len1-len2, str2) == 0)
             {
                 cnt++;
             }
        }
        printf("%d\n",cnt);
    }
    return 0;
}
发表于 2022-06-19 22:18:31 回复(0)
//将每个数的平方按照数位大小取余得到尾数在比较即可
#include <stdio.h>
#include <stdlib.h>
int main()
{
    int number = 0;
    int size = 0;
    int count = 0;
    scanf("%d",&number);
    for (int i = 0;i <= number;i++)
    {
        size  = pow(i,2);
        //想象一下该如何把尾数取出来?(87909376 % 10000 == 9376)
        if (size == i|| size % 10 == i || size % 100 == i || size % 1000 == i ||
           size % 10000 == i || size % 100000 == i)
        {
            count++;
        }   
    }
    printf("%d",count);
    return 0;
}

发表于 2022-05-14 16:48:04 回复(0)
#include<stdio.h>
int  isequitdata(int num){
    int seq = num*num;
    while(num!=0){
        if(num%10 == seq%10) {
            num = num/10;
            seq = seq/10;
        }
        else return 0;
    }
     return 1;
}
int main()
{
    int data=0;
    scanf("%d",&data);
    int count=0;
    for(int i=0;i<=data;i++){
        if(isequitdata(i)==1)count++;
    }
    printf("%d\n",count);
    
发表于 2022-05-12 14:11:22 回复(0)
#include <stdio.h>
#include <string.h>
#define    N    10
void transport(int x,char str[])
{
    int i=0;
    while(x>0)
    {
        str[i++]=x%10+'0';
        x/=10;
    }
}
int main()
{
    int n,i,j,temp,len,cnt=0;
    char num[N],square[N];
    scanf("%d",&n);
    for(i=0;i<=n;i++)
    {
        for(j=0;j<N;j++)
        {
            num[j]='\0';
            square[j]='\0';
        }
        temp=i*i;
        transport(i,num);
        transport(temp,square);
        len=strlen(num);
        for(j=0;j<len;j++)
        {
            if(num[j]!=square[j])
                break;
        }
        if(j==len)
            cnt++;
    }
    printf("%d\n",cnt);
    return 0;
}

发表于 2022-04-26 16:51:20 回复(0)
两个数对10取余进行比较,然后再对10取除,循环。
#include<stdio.h>
int main(){
    int n;
    while(~scanf("%d",&n)){
        int count=0;
        for(int i=1;i<=n;i++){
            int m=i,n=i*i;
            while(m>0){
                if(m%10!=n%10) break;
                m /=10;
                n /=10;
                if(m==0) count++;
            }
        } printf("%d\n",count+1);   
    }
}

发表于 2022-04-02 15:04:20 回复(0)
面向结果编程:
第一种:
#include<stdio.h>

int IsSelfEnd(int n){
    int div1;
    int temp=n*n;
    if(n<10){
        div1=10;
    }
    else if(n<100){
        div1=100;    
    }
    else if(n<1000){
        div1=1000;    
    }
    else if(n<10000){
        div1=10000;    
    }
    if((temp-n)%div1==0)
        return 1;
    return 0;
}


int main(){
    int f[10001];
    f[0]=1;
    for(int i=1;i<10000;i++){
        f[i]=f[i-1]+IsSelfEnd(i);
    }
    f[10000]=f[9999];
    int in;
    while(scanf("%d",&in)!=EOF){
        printf("%d\n",f[in]);
    }
    return 0;
}
第二种直接:
#include<stdio.h>


int main(){
    int comp[9]={0,1,5,6,25,76,376,625,9376};
    int in;
    while(scanf("%d",&in)!=EOF){
        if(in>=comp[8]){
            printf("%d\n",9);
            continue;
        }
        for(int i=0;i<9;i++){
            if(in<comp[i]){
                printf("%d\n",i);
                break;
            }
        }
    }
    return 0;
}



发表于 2022-01-25 12:33:46 回复(0)
#include<stdio.h>
#define Size 10

int is_zss(int n)
{
    int b[Size],c[Size];
    int count=0;
    int t=n;
    int cnt=1;

    if(n==0);
    else{
    
    for(int i=0;n!=0;i++){//取整数位数运算
        b[i]=n%10;
        n/=10;
        count++;
    }
  
    int sq=t*t;
    for(int j=0;j<count;j++){
        c[j]=sq%10;
        sq/=10;
    }

    for(int i=0;i<count;i++){
        if(b[i]-c[i]!=0) cnt=0;
        }
    }

    //printf("cnt=%d\n",cnt);

    return cnt;
}

int main()
{
    int n;
    int count=0;//零元素始终都是。
    while(scanf("%d",&n)!=EOF){
        for(int i=0;i<=n;i++){
            int cnt=is_zss(i);
            if(cnt==1){
                count++;
            }
        }
        printf("%d\n",count);
        count=0;
    }
    return 0;
}
发表于 2022-01-21 11:52:21 回复(0)
int c,d=0;
    while(scanf("%d",&c) != EOF){
        char a[5],b[10];
        int count = 0;
        for(int i = 0; i<=c; i++){
            d = i*i;
            sprintf(a,"%d",i);
            sprintf(b,"%d",d);
            int e,f,tag=1;
            e = strlen(a);
            f = strlen(b);
            char *p = a+e-1;
            char *q = b+f-1;
            while(*p){
//        if(*p-- != *q--){
//            break;
//        }
                if(*p != *q){
                    tag = 0;
                }
                *p--;
                *q--;
            }
            if(tag == 1){
                ++count;
            }
        }
        printf("%d\n",count);
    }
ide正常  这上面跑不出来
发表于 2021-12-06 15:23:41 回复(0)
先求出SIZE内所有的自守数,再查表寻找即可
#include <stdio.h>
#include <string.h>

#define SIZE 10000
int arr[100];    //自守数数组

void getnum(int size);
int checknum(int num);

int main(void)
{
    getnum(SIZE);
    int num;
    
    while(scanf("%d",&num)!=EOF){
        printf("%d\n",checknum(num));
    }
    
    return 0;
}

void getnum(int size)
{
    int i,j,tmp;
    
    arr[0] = 1,arr[1] = 5,arr[2] = 6;    //前四个自守数易得
    for(i=7,j=3;i<=size;i++){
        if(i<10) tmp = 10;
        else if(i<100) tmp = 100;
        else if(i<1000) tmp = 1000;
        else if(i<10000) tmp = 10000;
        else tmp = 100000;
        if((i*i - i) % tmp == 0){
            arr[j++] = i;    //记录自守数
        }
    }
}

int checknum(int num)
{
    int i = 0;        //因为要判断0,所以自守数数组内没有0,输出要+1多一个
    while(num >= arr[i] && arr[i]!=0) i++;
    return i+1;
}


发表于 2021-11-08 22:34:26 回复(0)

问题信息

难度:
21条回答 42729浏览

热门推荐

通过挑战的用户

查看代码
自守数