| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 649 人关注过本帖
标题:利用深度优先搜索解决水仙花数问题
取消只看楼主 加入收藏
巧若拙
Rank: 4
来 自:宁波余姚
等 级:业余侠客
威 望:1
帖 子:159
专家分:273
注 册:2014-8-24
结帖率:46.15%
收藏
 问题点数:0 回复次数:0 
利用深度优先搜索解决水仙花数问题
题目描述:
水仙花数是指一个N位正整数(N>=3),它的每个位上的数字的N次幂之和等于它本身。例 如:153 = 1^3 + 5^3+ 3^3。
 本题要求编写程序,计算所有N位水仙花数。
输入格式:
输入在一行中给出一个正整数N(3<=N<=7)。
输出格式:
按递增顺序输出所有N位水仙花数,每个数字占一行。
输入样例:
3
输出样例:
153
370
371
407
算法分析:
本题是穷举法的典型应用。我们可以设置一个数组来存储每一位数字,然后采用深度优先搜索(类似穷举全排列的方法),组合出每一个n位数,然后判断其是否为水仙花数。我实现了递归和非递归两种算法,并对求幂的算法进行了优化。奇怪的是非递归算法竟然比递归算法还要慢,真是不得其解,还望大牛指点。
说明:
算法思想:穷举法,深度优先搜索
数据结构:数组。
时间复杂度: O(10^n);
程序代码:
#include<stdio.h>
#include<stdlib.h>
#include <time.h>

int Num[10] = {0};

void dfs(int top, int n);//回溯法求水仙花数 
int pow(int a, int n);//递归法求幂 
void DaffodilNumber(int n);//穷举法求水仙花数(非递归) 

int main(void)
{
    clock_t start, finish;  
       double  duration;  
       int i, n;
       
       scanf("%d", &n);
       start = clock(); 
       for (i=1; i<10; i++) //回溯法求水仙花数,最高位不能为0 
    {
        Num[0] = i;
        dfs(1, n);
    }
    finish = clock();  
       duration = (double)(finish - start) / CLOCKS_PER_SEC;  
       printf( "%f seconds\n", duration );  
    
       start = clock(); 
       DaffodilNumber(n);//穷举法求水仙花数(非递归) 
       finish = clock();  
       duration = (double)(finish - start) / CLOCKS_PER_SEC;  
       printf( "%f seconds\n", duration );  
    
    return 0;
}

void dfs(int top, int n)//回溯法求水仙花数 
{
    int i, s1, s2;
    
    if (top == n)
    {
        s1 = s2 = 0;
        for (i=0; i<n; i++)
        {
            s1 += pow(Num[i], n);
            s2 = s2 * 10 + Num[i];
        }
        if (s1 == s2)
        {
            for (i=0; i<n; i++)
                printf("%d", Num[i]);
            printf("\n");
        }
        return ;
    }
    
    for (i=0; i<10; i++)
    {
        Num[top] = i;
        dfs(top+1, n);
    }
}

int pow(int a, int n)//递归法求幂 
{
    int s;
    
    if (a == 0 || a == 1 || n == 1)
        return a;
    if (n == 0)
        return 1;
        
    s = pow(a, n/2);
        
    return (n%2 == 0) ? (s * s) : (s * s * a);
}

void DaffodilNumber(int n)//穷举法求水仙花数(非递归) 
{
    int i, j, top, s1, s2;
    
    for (i=1; i<10; i++)
    {
        Num[0] = i;
        Num[1] = -1;
        top = 1;
        while (top > 0)
        {
            if (top == n)
            {
                s1 = s2 = 0;
                for (j=0; j<n; j++)
                {
                    s1 += pow(Num[j], n);
                    s2 = s2 * 10 + Num[j];
                }
                if (s1 == s2)
                {
                    for (j=0; j<n; j++)
                        printf("%d", Num[j]);
                    printf("\n");
                }
                --top; //返回上一个数字 
            }
            else if (Num[top] < 9)
            {
                Num[top++]++;
                Num[top] = -1;
            }
            else
            {
                --top;
            }
        }
    }
}
搜索更多相关主题的帖子: 编写程序 水仙花 正整数 
2014-11-23 21:22
快速回复:利用深度优先搜索解决水仙花数问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.017993 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved