程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 求解10位數以內的水仙花數:普通的窮舉算法 另:優化的深度優先搜索算法。

求解10位數以內的水仙花數:普通的窮舉算法 另:優化的深度優先搜索算法。

編輯:C++入門知識

[cpp]
/*
水仙花數是指一個 n 位數 ( n≥3 ),它的每個位上的數字的 n 次冪之和等於它本身。
(例如:1^3 + 5^3 + 3^3 = 153)
普通的窮舉算法,
CPU0: Intel(R) Pentium(R)
CPU P6200  @ 2.13GHz
求解8位數以內的水仙花數需要45s左右的時間,
 
*/ 
 
/**
@author : 東海陳光劍 2013.4.26 Friday ,01:02
 
*/ 
 
#include <stdio.h>  
#include <stdlib.h>  
#include <time.h>  
 
//#include <math.h>  
 
/* 求1-N 以內的水仙花數 */ 
#define N 1e8  
//typedef enum {true = 0, false = !true} bool;  
 
/**
打印日志時間
*/ 
void print_time() 

    time_t my_time; // time_t  
/*
    時間類型(time.h 定義)
struct tm -- 時間結構,time.h 定義如下:
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday;
int tm_yday;
int tm_isdst;
 
*/ 
    struct tm* timeinfo; 
    time( &my_time );//獲取時間,以秒計,從1970年1月一日起算,存於my_time  
    timeinfo = localtime( &my_time );//轉為當地時間,tm 時間結構  
    //printf ( "\007The current date is: %s", asctime (timeinfo) );  
/*asctime()-- 轉為標准ASCII時間格式:星期 月 日 時:分:秒 年*/ 
 
    printf ( "[%4d-%02d-%02d %02d:%02d:%02d]", 
            1900+timeinfo->tm_year, 
            1+timeinfo->tm_mon, 
            timeinfo->tm_mday, 
            timeinfo->tm_hour, 
            timeinfo->tm_min, 
            timeinfo->tm_sec); 
/*
打印tm,tm_year 從1900年計算,所以要加1900,
月tm_mon,從0計算,所以要加1 */ 
 

 
 
/**
取數字位數
*/ 
int get_power_index(int n) 

 
    int power_index = 0; 
    while (n > 0) 
    { 
        power_index ++; 
        n /= 10; 
    } 
 
    return power_index; 

 
/**計算數字各位上數字的k次方(k=數字的位數)*/ 
 
int my_pow(int* a, int* b) 

    int i=0; 
    int p=1; 
    //int pow = 1;  
    for (i = 0; i < *b; i++) 
    { 
      p *= *a; 
    } 
 
    return p; 

 
/**判斷x是否是水仙花數*/ 
int is_flower(int x) 

    int sum = 0; 
    int a = 0; 
    //int* pindex =NULL;  
    int pindex = get_power_index( x ); 
   // int bits = power_index;  
    int n=x; 
 
    while (n > 0) 
    { 
        a = n % 10; 
        sum += my_pow( & a , & pindex); 
        n = (( n - n % 10 )/10);// n去尾  
    } 
 
 
    if (x == sum ) 
    { 
       // printf(" %d 位數: ",*pindex);  
        return 0; 
    } 
    else 
    { 
        return 1; 
    } 

 
 
 
int main() 

    // test  
    print_time(); 
    printf("Testing....\nThe result is 9,625,010001000\n"); 
    //printf("%c\n",ctime(gmtime()));  
    int a=5; 
    int b=4; 
    printf("%d\n",get_power_index(124667459));// 9  
    printf("%d\n",my_pow(&a,&b));// 625  
 
    printf("%d\n",is_flower(153));//0  
    printf("%d\n",is_flower(875));//1  
    printf("%d\n",is_flower(370));//0  
    printf("%d\n",is_flower(371));//0  
    printf("%d\n",is_flower(407));//0  
    printf("%d\n",is_flower(934));//1  
    printf("%d\n",is_flower(93084));//0  
    printf("%d\n",is_flower(92727));//0  
    printf("%d\n",is_flower(54748));//0  
 
 
    print_time(); 
    printf("求1- %lf 以內的水仙花數.....\n",N); 
 
 
    int i; 
 
    clock_t start, finish; 
    double duration; 
 
    //printf("%c\n",ctime(gmtime()));  
 
    start = clock(); // 計時開始  
 
    // 窮舉算法  
    for(i=1;i<N;i++) 
    { 
        if(is_flower(i) == 0) 
        { 
            printf("%d位數的水仙花:%d\n",get_power_index(i),i); 
        } 
    } 
 
    print_time(); 
 
    finish = clock(); //計時結束  
 
    //printf("%c\n",ctime(gmtime()));  
 
       /* 測量一個事件持續的時間*/ 
    duration = (double)(finish - start) / CLOCKS_PER_SEC; 
    printf( "Time using is %f seconds\n", duration ); 
      //system("pause");  
 
    return 0; 

/*
水仙花數是指一個 n 位數 ( n≥3 ),它的每個位上的數字的 n 次冪之和等於它本身。
(例如:1^3 + 5^3 + 3^3 = 153)
普通的窮舉算法,
CPU0: Intel(R) Pentium(R)
CPU P6200  @ 2.13GHz
求解8位數以內的水仙花數需要45s左右的時間,

*/

/**
@author : 東海陳光劍 2013.4.26 Friday ,01:02

*/

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

//#include <math.h>

/* 求1-N 以內的水仙花數 */
#define N 1e8
//typedef enum {true = 0, false = !true} bool;

/**
打印日志時間
*/
void print_time()
{
    time_t my_time; // time_t
/*
    時間類型(time.h 定義)
struct tm -- 時間結構,time.h 定義如下:
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday;
int tm_yday;
int tm_isdst;

*/
    struct tm* timeinfo;
    time( &my_time );//獲取時間,以秒計,從1970年1月一日起算,存於my_time
    timeinfo = localtime( &my_time );//轉為當地時間,tm 時間結構
    //printf ( "\007The current date is: %s", asctime (timeinfo) );
/*asctime()-- 轉為標准ASCII時間格式:星期 月 日 時:分:秒 年*/

    printf ( "[%4d-%02d-%02d %02d:%02d:%02d]",
            1900+timeinfo->tm_year,
            1+timeinfo->tm_mon,
            timeinfo->tm_mday,
            timeinfo->tm_hour,
            timeinfo->tm_min,
            timeinfo->tm_sec);
/*
打印tm,tm_year 從1900年計算,所以要加1900,
月tm_mon,從0計算,所以要加1 */

}


/**
取數字位數
*/
int get_power_index(int n)
{

    int power_index = 0;
    while (n > 0)
    {
        power_index ++;
        n /= 10;
    }

    return power_index;
}

/**計算數字各位上數字的k次方(k=數字的位數)*/

int my_pow(int* a, int* b)
{
    int i=0;
    int p=1;
    //int pow = 1;
    for (i = 0; i < *b; i++)
    {
      p *= *a;
    }

    return p;
}

/**判斷x是否是水仙花數*/
int is_flower(int x)
{
    int sum = 0;
    int a = 0;
    //int* pindex =NULL;
    int pindex = get_power_index( x );
   // int bits = power_index;
    int n=x;

    while (n > 0)
    {
        a = n % 10;
        sum += my_pow( & a , & pindex);
        n = (( n - n % 10 )/10);// n去尾
    }


    if (x == sum )
    {
       // printf(" %d 位數: ",*pindex);
        return 0;
    }
    else
    {
        return 1;
    }
}

 

int main()
{
    // test
    print_time();
    printf("Testing....\nThe result is 9,625,010001000\n");
    //printf("%c\n",ctime(gmtime()));
    int a=5;
    int b=4;
    printf("%d\n",get_power_index(124667459));// 9
    printf("%d\n",my_pow(&a,&b));// 625

    printf("%d\n",is_flower(153));//0
    printf("%d\n",is_flower(875));//1
    printf("%d\n",is_flower(370));//0
    printf("%d\n",is_flower(371));//0
    printf("%d\n",is_flower(407));//0
    printf("%d\n",is_flower(934));//1
    printf("%d\n",is_flower(93084));//0
    printf("%d\n",is_flower(92727));//0
    printf("%d\n",is_flower(54748));//0


    print_time();
    printf("求1- %lf 以內的水仙花數.....\n",N);


    int i;

    clock_t start, finish;
    double duration;

    //printf("%c\n",ctime(gmtime()));

    start = clock(); // 計時開始

    // 窮舉算法
    for(i=1;i<N;i++)
    {
        if(is_flower(i) == 0)
        {
            printf("%d位數的水仙花:%d\n",get_power_index(i),i);
        }
    }

    print_time();

    finish = clock(); //計時結束

    //printf("%c\n",ctime(gmtime()));

       /* 測量一個事件持續的時間*/
    duration = (double)(finish - start) / CLOCKS_PER_SEC;
    printf( "Time using is %f seconds\n", duration );
      //system("pause");

    return 0;
}


/*
#include <stdio.h>
#include <time.h>

void main ()
{
time_t rawtime;
struct tm * timeinfo;

time ( &rawtime );
timeinfo = localtime ( &rawtime );
printf ( "\007The current date/time is: %s", asctime (timeinfo) );

exit(0);
}

=================
#include <time.h>  -- 必須的時間函數頭文件
time_t -- 時間類型(time.h 定義)
struct tm -- 時間結構,time.h 定義如下:
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday;
int tm_yday;
int tm_isdst;

time ( &rawtime ); -- 獲取時間,以秒計,從1970年1月一日起算,存於rawtime
localtime ( &rawtime ); -- 轉為當地時間,tm 時間結構
asctime ()-- 轉為標准ASCII時間格式:
星期 月 日 時:分:秒 年
=========================================
你要的格式可這樣輸出:
 printf ( "%4d-%02d-%02d %02d:%02d:%02d\n",1900+timeinfo->tm_year, 1+timeinfo->tm_mon,
timeinfo->tm_mday,timeinfo->tm_hour,timeinfo->tm_min,timeinfo->tm_sec);

就是直接打印tm,tm_year 從1900年計算,所以要加1900,
月tm_mon,從0計算,所以要加1
其它你一目了然啦。
*/

 

/*
#include<math.h>

函數原型是:
1.double pow(double _X,double _Y);
2.double pow(double _X,int _Y);
3.long double pow(long double _X,long double _Y);
4.long double pow(long double _X,int _Y);
5.float pow(float _X,float _Y);
6.float pow(float _X,int _Y);

原型:extern float pow(float x, float y);

  用法:#include

  功能:計算x的y次冪。

  說明:x應大於零,返回冪指數的結果。

  舉例:

      // pow.c

      #include
      #include
      #include
     void main()
      {
        printf("4^5=%f",pow(4.,5.));
        getchar();
      }
#include
#include

void main( void )
{
   double x = 2.0, y = 3.0, z;

   z = pow( x, y );
   printf( "%.1f to the power of %.1f is %.1f ", x, y, z );
}


Output

2.0 to the power of 3.0 is 8.0


*/

 

/*
整型          [signed]int                  -2147483648~+2147483648
無符號整型unsigned[int]                       0~4294967295
短整型 short [int]                                    -32768~32768
無符號短整型unsigned short[int]             0~65535
長整型 Long int                            -2147483648~+2147483648
無符號長整型unsigned [int]                   0~4294967295
字符型[signed] char                               -128~+127
無符號字符型 unsigned char                       0~255
單精度 float                                 3.4 x 10^(-38)~  3.4 x 10^(+38)
雙精度double                              1.7 x 10^(-308)~  1.7 x 10^(+308)
長雙精度 long double                 1.7 x 10^(-308)~  1.7 x 10^(+308)
*/

/*
time()     取得本地時間(日期時間函數)
settimeofday()     設置當前時間戳
mktime()     將時間結構數據轉換成經過的秒數
localtime()     獲取當地目前時間和日期
gmtime()     獲取當前時間和日期
gettimeofday()     獲取當前時間
ctime()     將時間日期以字符串格式表示
asctime()     將時間日期以字符串格式表示

printf("%s\n",ctime(gmtime()));

 

 

*/

 

/*
常見水仙花數
水仙花數又稱阿姆斯特朗數。
水仙花數

  水仙花數
三位的水仙花數共有4個:153,370,371,407;四位的水仙花數共有3個:1634,8208,9474;
五位的水仙花數共有3個:54748,92727,93084;
六位的水仙花數只有1個:548834;
七位的水仙花數共有4個:1741725,4210818,9800817,9926315;
八位的水仙花數共有3個:24678050,24678051,88593477
……
……
使用高精度計算,可以得到超過INT類型上限的水仙花數:
5: 93084
5: 92727
5: 54748
6: 548834
7: 9800817
7: 4210818
7: 1741725
7: 9926315
8: 24678050
8: 24678051
8: 88593477
9: 146511208
9: 912985153
9: 472335975
9: 534494836
10: 4679307774
11: 32164049650
11: 40028394225
11: 42678290603
11: 49388550606
11: 32164049651
11: 94204591914
11: 44708635679
11: 82693916578
14: 28116440335967
16: 4338281769391370
16: 4338281769391371
17: 35875699062250035
17: 21897142587612075
19: 3289582984443187032
19: 4929273885928088826
19: 4498128791164624869
20: 63105425988599693916
21: 449177399146038697307
21: 128468643043731391252
23: 27907865009977052567814
23: 35452590104031691935943
23: 27879694893054074471405
23: 21887696841122916288858
24: 174088005938065293023722
24: 188451485447897896036875
(為環保起見,24位以上的水仙花數略)
理論上,最大的水仙花數不超過34位。
*/

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved