2011年4月28日 星期四

a040: 阿姆斯壯數

內容
所謂 Armstrong number 指的是一個 n 位數的整數,它的所有位數的 n 次方和恰好等於自己。

如:1634 = 14 + 6+ 34+ 44 

請依題目需求在一定範圍內找出該範圍內的所有 armstrong numbers.

輸入說明
輸入包含兩個數字n, m(n0, m<=1000000),代表所有尋找 armstrong number 的範圍

輸出說明
將所有範圍內的 armstrong number 依序由小到大輸出,如果沒有找到請輸出 none.

範例輸入
100 999
10 99

範例輸出
153 370 371 407
none

程式碼1 :(重頭算到尾的寫法)
#include <stdio.h>

int main()
{
    int a,b,i,j,k,len=4,sum,one_num_sum,temp,index;
    int arr[25];
    int num[8];
    
    for(i=1,index=0;i<1000000;i++)
    {
        temp = i;
        for(len=0;temp!=0;len++)
        {
            num[len] = temp % 10;
            temp = temp / 10;
        }
        sum = 0;
        for(j=0;j<len;j++)
        {
            for(k=0,one_num_sum=num[j];k<len-1;k++)
                one_num_sum = one_num_sum * num[j];
            sum = sum + one_num_sum;
        }
        if(i == sum)
        {
            arr[index++] = sum;
        }
    }
    while(scanf("%d%d",&a,&b)==2)
    {
        for(i=0; i<index && a>arr[i]; i++);
        b++;
        if(b > arr[i])
        {
            for(;i<index && b>arr[i];i++)
                printf("%d ",arr[i]);
            printf("\n");
        }
        else
            printf("none\n");
        
    }
    return 0;
}

程式碼2 :(已經算好結果的寫法)
#include <stdio.h>

int main()
{
    int a,b,i,index;
    int arr[20]={1,2,3,4,5,6,7,8,9,153,370,371,407,1634,8208,9474,54748,92727,93084,548834};
        
    index = 20;
    while(scanf("%d%d",&a,&b)==2)
    {
        for(i=0; i<index && a>arr[i]; i++);
        b++;
        if(b > arr[i])
        {
            for(;i<index && b>arr[i];i++)
                printf("%d ",arr[i]);
            printf("\n");
        }
        else
            printf("none\n");
    }
    return 0;
}



http://zerojudge.tw/ShowProblem?problemid=a040

6 則留言:

  1. 不好意思,可以教導我一下你程式碼一的寫法嗎?
    我看不懂,謝謝

    回覆刪除
  2. 我舉個例子並配合著行數給你參考
    1.第9~28行是從1~1000000中找出符合阿姆斯壯數的數字

    2.第12~16行把數字拆開並用陣列存起來,例如 temp = 987會存成 num = {7,8,9}的形式

    3.第18~23行把每個num的值透過阿姆斯壯算法算出結果,以上述例子為 7*7*7 + 8*8*8 + 9*9*9
    3.1.第20~21行是把每個num的值*n次,以num[0]為例 = 7*7*7
    3.2.第22行是把每個上一個步驟計算的結果加起來,例如 sum = sum + 7*7*7;

    4.第24~27行,如果987 == 7*7*7 + 8*8*8 + 9*9*9 的話,就會記錄到第26行,但是事實上並沒有相等,所以不會儲存。

    如果有哪一行看不懂的話再和我說一下。

    回覆刪除
  3. 我自己想到的方法寫起來好複雜,這個好簡潔明瞭,感謝分享!

    回覆刪除
  4. #include
    #include
    #include
    int power(int,int);
    int separateNum(char);
    char separateChar(int);
    int judge(char*);
    int valuee(char*);
    char* numToChar(int);


    int main(){
    int upper,lower;
    while(scanf("%d %d",&lower,&upper)!=EOF){
    int switcH =0;
    for (int i=lower;i<=upper;i++){
    if (judge(numToChar(i))==1){
    printf("%d ",i);
    switcH=1;
    }
    }
    if(switcH==0) printf("none");
    printf("\n");
    }
    return 0;
    }


    char* numToChar(int a){
    char k[100];
    int num[100];
    int size=0;
    for(int i=0;a!=0;i++){
    num[i]=(a%(power(10,i+1)))/power(10,i);
    a=a-num[i]*power(10,i);
    size++;
    }
    for(int i=0;i<=(size-1);i++){
    k[i]=separateChar(num[size-1-i]);
    }
    k[size]='\0';
    return k;
    }




    int valuee(char* c){
    int len=strlen(c);
    int temp=0;
    for(int i=0;i<len;i++){
    temp=temp+separateNum(c[i])*power(10,len-1-i);
    }
    return temp;
    }

    int judge(char*c){
    int len,value=0,armstrongSum=0;
    len=strlen(c);
    for(int i=0;i<len;i++){
    armstrongSum=armstrongSum+power(separateNum(c[i]),len);
    }
    if (valuee(c)==armstrongSum) return 1;
    else return 0;
    }

    int power(int a,int b){
    int temp=a;
    for(int i=1;i<b;i++) temp=temp*a;
    if (b!=0) return temp;
    else return 1;
    }

    int separateNum(char c){
    if (c=='9') return 9;
    if (c=='8') return 8;
    if (c=='7') return 7;
    if (c=='6') return 6;
    if (c=='5') return 5;
    if (c=='4') return 4;
    if (c=='3') return 3;
    if (c=='2') return 2;
    if (c=='1') return 1;
    if (c=='0') return 0;
    }

    char separateChar(int a){
    if(a==0) return '0';
    if(a==1) return '1';
    if(a==2) return '2';
    if(a==3) return '3';
    if(a==4) return '4';
    if(a==5) return '5';
    if(a==6) return '6';
    if(a==7) return '7';
    if(a==8) return '8';
    if(a==9) return '9';
    }

    您好這是我的寫法 在dev cpp上跑都是對的

    可是測資的時候就WA(line 1) 預期答案153 370 371 407

    但他說我輸出100 101 102....

    可以幫我看一下嗎?

    回覆刪除
  5. 你錯的地方真是讓我學了一課阿!
    錯的地方在char* numToChar(int a)的char k[100];
    k的位置雖然有傳回到主程式,但是別忘了,因為你的k是在numToChar,而不是main,所以回到main時,numToChar這個function已經結束了,所以k的位置可以給別人使用,當你又要使用時,k的值已經被別人改掉了,當然你抓的值就有可能錯誤(如果沒有被改到就不會有錯誤了)。
    解決方法有兩種,
    第一是static char k[100];
    第二是在main把numToChar的回傳存起來,再使用。

    回覆刪除
    回覆
    1. 哦哦原來是這樣啊

      謝謝您的解答XDDD真的獲益匪淺

      (這部份真的不太熟 要在練一下了QQ)

      刪除