zoukankan      html  css  js  c++  java
  • 18005 It is not ugly number

    18005 It is not ugly number

    时间限制:2000MS  内存限制:65535K
    提交次数:0 通过次数:0

    题型: 编程题   语言: G++;GCC

     

    Description

    Ugly numbers are numbers whose only prime factors are 2, 3 or 5. The sequence1, 2, 3, 4, 5, 6, 8, 9, 10, 12, ...shows the 
    first 10 ugly numbers. By convention, 1 is included. Then, here are the first 10 Not ugly numbers:7, 11, 13, 14, 17, 19, 
    21, 22, 23, 26. Given the integer n, write a program to find and print the n'th Not ugly number.
    




    输入格式

    First line is T(T<=10000), the number of cases.
    The T lines following. Each line of the input contains a positive integer n (n <= 100000000).
    



    输出格式

    For each case, output the n'th Not ugly number .
    



     

    输入样例

    3
    1
    2
    9
    



     

    输出样例

    7
    11
    23
    



     

    作者

     admin

      要求第n项非丑数;无疑要先利用数学知识求出丑数。我的做法是先预处理前1200个丑数,至于为什么只用处理这个数量的丑数是自己试出来的;可能你会疑惑为什么只用处理一千多个就行了,,因为丑数是因子只含有2、3和5的数字,所以越往后面数字越大它继越有可能包含有不止这三个数的因子;所以前几百项的丑数序列看似是挺密集的,但越到后面每两个丑数间的间隔就越大。而我们要找的第n项非丑数,肯定就在某两个丑数之间。

      所以题目唯一的难点就在于求出丑数。我这里用的是优先队列来预处理。  一开始,我们知道前几项丑数:1、2、3、5;那么 如果要得出接下来同样也是因子只有2、3、5的丑数,就只需要将前面这几个已知道的丑数分别乘以2、3、5得出来的数,那它的因子同样一定是只有2、3、5的。  但是,如果将每一项都乘以这三个数的话,你会发现有重复的数字出现。因而这里要用到一个技巧:给每一个数字加多一个标记,用来标注当前这个丑数是由前面的丑数乘以哪个数字得出来的;所以用到了pair<int,int>。第一个数据域存放这个丑数的值,第二个则用来存放标记值。   比如用2分别乘以2、3、5得到4、6、10,那么得到三个pair为<4,2>、<6,3>、<10,5>;然后将这三个pair存入优先队列中去,弹出2;每次再取出最小的丑数(要从小到大取再加上刚刚说的技巧才能避免重复);假设取到pair<6,3>的时候,这时你就只能将6分别乘以3和5,而不能乘2 ( 因为前面会有<4,2>中的4乘以3得到12发生重复 )。   另外,关于得出了丑数之后再求非丑数的技巧写在了代码注释中了。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cstdlib>
     5 #include <cctype>
     6 #include <cmath>
     7 #include <algorithm>
     8 #include <set>
     9 #include <map>
    10 #include <queue>
    11 #include <stack>
    12 #include <utility>
    13 #include <vector>
    14 #define ll long long
    15 #define inf 0x3f3f3f3f
    16 #define MAXN 100000
    17 using namespace std;
    18 
    19 typedef pair<int,int> node_type;
    20 int res[1500];
    21 int main()
    22 {
    23     //freopen("input.txt","r",stdin);
    24     priority_queue<node_type,vector<node_type>,greater<node_type> > pq;//用来存放pair的优先队列,默认是比较pair中的第一个元素,greater<>则另其每次去最小的数据
    25     pq.push(node_type(1,2)); //压入第一个丑数
    26     node_type temp;
    27     for(int i=0; i<1205; i++)
    28     {
    29         temp=pq.top(); //取队列首,也就是当前队列中最小的丑数
    30         switch(temp.second)  //由pair<>的第二个元素判断当前这个丑数是由哪个标记值生成的;然后继续生成新的丑数
    31         {
    32         case 2:
    33             pq.push(make_pair(temp.first*2,2));
    34         case 3:
    35             pq.push(make_pair(temp.first*3,3));
    36         case 5:
    37             pq.push(make_pair(temp.first*5,5));
    38         }
    39         res[i]=temp.first;
    40         pq.pop();
    41     }
    42     //处理完丑数后
    43     int t,n,cnt,i;
    44     scanf("%d",&t);
    45     while(t--)
    46     {
    47         scanf("%d",&n);
    48         cnt=0;
    49         i=0;
    50         while(cnt<n) //cnt标记当前已寻找到的第cnt项的非丑数
    51         {
    52             cnt+=(res[i+1]-res[i++]-1);//cnt每次加上的值是每相邻两个丑数的差,这个差即这两个丑数之间包含的非丑数的个数
    53         }
    54         //找到所要的第n项非丑数在哪两个丑数之间后退出循环
    55         i--;
    56         cnt-=(res[i+1]-res[i]-1);//从这个丑数区间的左边开始算,res[i]加上n-cnt就是第n项丑数了
    57         printf("%d
    ",res[i]+n-cnt);
    58     }
    59     return 0;
    60 }
  • 相关阅读:
    数据库完整性约束
    系统介绍
    全栈性能测试修炼宝典--Jmeter实战(一)
    数据驱动(四)
    数据驱动(五)
    数据驱动(三)
    数据驱动(二)
    数据驱动(一)
    Robot Framework 三种测试用例模式
    sublime text---注释
  • 原文地址:https://www.cnblogs.com/geek1116/p/5548705.html
Copyright © 2011-2022 走看看