B1091 N-自守數 (15分)
阿新 • • 發佈:2019-01-20
length 是否 題目 sca 位數 數字 etc esp 一次 。註意題目保證 \(N<10\)。
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
輸入樣例:
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分)