1. 程式人生 > >B1091 N-自守數 (15分)

B1091 N-自守數 (15分)

length 是否 題目 sca 位數 數字 etc esp 一次

B1091 N-自守數 (15分)

如果某個數 \(K\)的平方乘以\(N\) 以後,結果的末尾幾位數等於 \(K\),那麽就稱這個數為“\(N\)-自守數”。例如 \(3×92 ?^2 ?=25392\),而 25392 的末尾兩位正好是 92,所以 92 是一個 3-自守數。

本題就請你編寫程序判斷一個給定的數字是否關於某個 N 是 N-自守數。

輸入格式:

輸入在第一行中給出正整數 \(M(≤20)\),隨後一行給出 \(M\) 個待檢測的、不超過 1000 的正整數。

輸出格式:

對每個需要檢測的數字,如果它是 \(N\)-自守數就在一行中輸出最小的 $N $和 \(NK ?^2\)
的值,以一個空格隔開;否則輸出 No

。註意題目保證 \(N<10\)

輸入樣例:

3
92 5 233

輸出樣例:

3 25392
1 25
No

思路

對0-9逐一檢驗
9000000
為什麽我的代碼有一個測試點過不去。
因為對0所有數都會自守的,對一些特殊的數要特別看待。

#include<bits/stdc++.h>
using namespace std;

int tmp_ans[9];
int ans[9];

int change(int a[],int b){
    int num = 0;
    while(b!=0){
        a[num++]=b%10;
        b/=10;
    }
    return num;
}
int main(void){
    int m,tmp,tmp_num,num,true_ans;
    int flag; 
    scanf("%d",&m);
    getchar();
    for(int i=0;i<m;i++){//對每個數都處理一次標記 
        flag = -1;
        scanf("%d", &tmp);//要判斷有幾位數,最大是4位 
        tmp_num=change(tmp_ans,tmp);
        for(int j=0;j<10;j++){
            flag = -1;
            true_ans=tmp*tmp*j;
            num=change(ans,true_ans);
            for(int k=0;k<tmp_num;k++){
                if(ans[k]!=tmp_ans[k]){
                    flag = k;
                    break;
                }       
            }
            if(flag==-1){
                printf("%d %d\n",j,true_ans);
                break;
            }        
        }
        if(flag!=-1)
            printf("No\n");/*無自守數*/
    }
    return 0;
}

AC代碼

/*消去0這個自守。*/
for(int j=1;j<10;j++)

來自別人的AC代碼

不是暴力而是數學的寫法。

作者:dk_qi
鏈接:https://www.jianshu.com/p/c59448ce5414

以題中\(3×92^2=25392\)為例,當數\(K\)\(92\),自守數\(N\)\(3\)時,有\((3×92×92-92)% 100 = 0\)。推廣即得
/[(NKK-K)%(10^{length(K)})=0]/

#include<stdio.h>

int len(int K);    //該函數返回10的K的長度次方。

int main()
{
    int M, K, l, flag;
    scanf("%d", &M);
    for(int i = 0; i < M; i++){
        scanf("%d", &K);
        l = len(K);
        flag = 0;    // flag標記K是否有自守數
        for(int j = 0; j < 10; j++){
            if((j * K * K - K) % l == 0){
                printf("%d %d\n", j, j*K*K);
                flag = 1;
                break;  //得到最小自守數後直接break
            }
        }
        if(flag == 0)    printf("No\n");
    } 
    return 0;
}

int len(int K){
    int len = 1;
    while(K){
        len *= 10;
        K /= 10;
    }
    return len;
}

B1091 N-自守數 (15分)