您的位置:首页 > 其它

例题5-7 丑数 UVa136

2016-11-17 18:14 323 查看
算法竞赛入门经典(第2版)
第5章C++与STL入门
例题5-7  丑数 
UVa136

感悟。

1、从网站下载英文原题,没想到内容半页不到,很快读懂,菜题一个。

2、基本思路,能被2整除,一直除2;能被3整除,一直除3;能被5整除,一直除5;最后值为1,则为丑数。

3、编好提交http://vjudge.net,Time
limit exceeded,菜题不菜,感受到竞赛题的威力。

4、用printf("Time used = %.2f\n",(double)clock()/CLOCKS_PER_SEC);测试时间23.21s,

5、这个思路http://blog.csdn.net/synapse7/article/details/11664577有点牛:可以用暴力先把答案算出来。

6、http://vjudge.net提交WA,一查,少了最后一个.号,修改,提交AC,在https://uva.onlinejudge.org/提交AC,看看时间,2016-11-17
18:39

7、对此题一直念念不忘,一丝想法飘过,set集合中元素不可重复,非1丑数,丑数/2或丑数/3或丑数/5必是丑数,马上编码,应该代码量很小,耗时明显较短。但上机一调试,耗时巨大。

8、通过http://www.cnblogs.com/flyoung2008/articles/2136485.html
http://www.cnblogs.com/void/archive/2012/02/01/2335224.html http://blog.csdn.net/rushkid02/article/details/7687125
三篇博客学习了优先队列,效果还不错。

9、点评书中代码,写点不一样的地方:

一、因每次插入2x,3x,5x,故用int必越界,所以用long
long,typedef方便原因有2,1是定义变量书写代码方便,2是方便测试,如typedef int LL;

二、因要查找队列中的元素,队列没有提供专门方法,故用set进行中转,所以set不能省;

三、将2,3,5放在整数数组中,写起代码for循环就搞定,不用2写一次,3写一次,5写一次。

四、因为处理的数据都是丑数,不存在非丑数的计算,所以运算量小了许多许多,所以写出的代码才能通过测试。

附上AC代码,编译环境Dev-C++4.9.9.2

#include <cstdio>

int main(){

    printf("The 1500'th ugly number is 859963392.\n");

}

以上AC代码的答案,来自Time limit exceeded代码,如下:

#include <iostream>

//#include <ctime>

//#include <cstdio>

using namespace std;

int main(){

    int i=0;

    int ans;

    int count=0;

    while(1){

        i++;

        ans=i;

        while(ans%2==0){

            ans/=2;

        }

        while(ans%3==0){

            ans/=3;

        }

        while(ans%5==0){

            ans/=5;

        }

        if(ans==1){

            count++;

        }

        if(count==1500)

            break;

    }

    cout<<"The 1500'th ugly number is "<<i<<endl;

//    printf("Time used = %.2f\n",(double)clock()/CLOCKS_PER_SEC);

    return 0;

}
两个代码造就了AC程序。此时2016-11-17 18:33

附上消化书中写的AC代码。

#include <iostream>

#include <queue>

#include <set>

using namespace std;

typedef long long LL;

int main(){

    LL x,x2;

    priority_queue<LL,vector<LL>,greater<LL> > pq;

    set<LL> s;

    int i;

    int coeff[3]={2,3,5};

    int j;

    

    pq.push(1);

    s.insert(1);

    for(i=1;;i++){

        x=pq.top();

        pq.pop();

        if(i==1500){

            cout<<"The 1500'th ugly number is "<<x<<"."<<endl;

            break;

        }

        for(j=0;j<3;j++){

            x2=x*coeff[j];

            if(!s.count(x2)){

                s.insert(x2);

                pq.push(x2);

            }

        }

    }

    return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: