HDU 1058 优先队列or堆

本来应当是一道优先队列或者堆的题 因为每个数都应该是已经得到的数*2 *3 *5 *7而得到的 但是 2*7 大于 3*2 这就必须保证每次取得都是没有拿过的最小的数

但是它主动降低难度在样例里卖了个萌 n的范围是1~5842 而第5842在样例里给出了..所以我们在取出一个数 求出它的*2 *3 *5 *7的时候做一下判断 如果大于最后一位就直接break 因为相乘的顺序在 可以省一点时间

在判断某个数是否出现过的时候 开不出那么大的vis数组 所以直接for循环从ans数组中寻找 所幸没有超时QAQ

尤其需要注意的是题目的思考并不难 但是输出的英语用法是坑

1 2 3 分别是 first second third 所以缩写的是 st nd rd

21 22 23 等 是 twenty - first twenty - second twenty- third 等 它们的缩写都是 st nd rd

但是11 12 13 不是.. 它们的第次缩写都是 th

(我的输出代码写得判断很麻烦..因为我懒得改..)

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<math.h>
#include<queue>
#include<iostream>
using namespace std;
long long int e[6050];
int w;
bool find(long long int x)
{
    for(int i=0;i<w;i++)
    {
        if(e[i]==x)
        return true;
    }
    return false;
}
void init()
{
    w=0;
    queue<long long int >q;
    q.push(2);
    q.push(3);
    q.push(5);
    q.push(7);
    e[w++]=1;
   e[w++]=2;e[w++]=3;e[w++]=5;e[w++]=7;
    while(!q.empty())
    {
       long long  int z=q.front();q.pop();
       /* if(w==5842)
        return ;*/
        for(int i=0;i<4;i++)
        {
            long long int x=z;
            ///if(x> 2000000000)continue;
            if(i==0)
            {
                x*=2;
                if(x> 2000000000)
                break;
                if(!find(x))
                {
                    e[w++]=x;
                    q.push(x);
                }
            }
            else if(i==1)
            {
                x*=3;
                if(x> 2000000000)
                break;
                if(!find(x))
                {
                    e[w++]=x;
                    q.push(x);
                }
            }
            else if(i==2)
            {
                x*=5;
                if(x> 2000000000)
                break;
                if(!find(x))
                {
                    e[w++]=x;
                    q.push(x);
                }
            }
            else if(i==3)
            {
                x*=7;
                if(x> 2000000000)
                break;
                if(!find(x))
                {
                    e[w++]=x;
                    q.push(x);
                }
            }

        }
    }

}
int main(){
init();
int n;
sort(e,e+w);
while(~scanf("%d",&n))
{
    if(n==0)
    break;
    if(n==11)
    printf("The 11th humble number is ");
    else if(n==12)
    printf("The 12th humble number is ");
    else if(n==13)
    printf("The 13th humble number is ");
    else
    {
        if(n%10!=1&&n%10!=2&&n%10!=3)
        {
            printf("The %dth humble number is ",n);
        }
        else if(n%10==1&&n%100!=11)
        {
            printf("The %dst humble number is ",n);
        }
        else if(n%10==2&&n%100!=12)
        {
            printf("The %dnd humble number is ",n);
        }
        else if(n%10==3&&n%100!=13)
        {
            printf("The %drd humble number is ",n);
        }
        else
        printf("The %dth humble number is ",n);
    }
   printf("%I64d.\n",e[n-1]);
}
}

  

时间: 2024-08-05 19:09:21

HDU 1058 优先队列or堆的相关文章

【数据结构】优先队列和堆

优先队列(priority queue) 对于一般的队列是在队列的尾部添加数据,在头部删除,以便先进先出. 而优先队列中的每个元素都有一个优先级,每次将一个元素放入队列中,而每次出队时都是将优先级最大的那个元素出队,称为高进先出(largest-in,first-out). 优先队列必须实现以下几个操作 1.入队(push):将一个元素放入队列中. 2.出队(pop):将优先级最高的元素从队列中删除. 要实现上面的操作可以维护一个有序的链表.每次插入数据时维护整个链表有序,即使用插入法,每次出队

toj 2196 优先队列和堆的用法

很简单的优先队列或者堆的使用. 1 #include <iostream> 2 #include <queue> 3 using namespace std; 4 5 //greater对int来说表示值越小优先级越高,也可以自己定义比较函数 6 priority_queue< int, vector<int>, greater<int> > q; 7 char op[2]; 8 9 int main () 10 { 11 int n; 12 w

hdu 1058 Humble Numbers || poj 1338(dp)

两题都是一样的题目 只是hdu 1058 多了个7 题意:求一个每个数因子仅含2 3 5 7 的 序列 问 第n个数是几 思路: ans[i]=min(min(ans[n2]*2,ans[n3]*3),min(ans[n5]*5,ans[n7]*7)); if(ans[i]==ans[n2]*2) n2++; if(ans[i]==ans[n3]*3) n3++; if(ans[i]==ans[n5]*5) n5++; if(ans[i]==ans[n7]*7) n7++; hdu 1058 #

hdu 2177 取(2堆)石子游戏

天资愚笨啊,网上的一大堆没看懂...... 总结百科的方法为: 1.a==b 同时减去a 得到0,0 2.a==a_k      b>b_k b -(b-b_k) 3.a==a_k     b<b_k 同时拿走a_k-a_(b-a_k) 得到 a_(b-a_k)    a_(b-a_k) + b-a_k 4.a>a_k       b==b_k 从a中拿走 a-a_k 5.a<a_k       b==b_k 5.1 a==a_ j   (j<k) b-(b-b_ j) 得到

hdu 1058

? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 题意:求素因子只有2 3 5 7的数<br>zsd:5842 各种打表<br>#include<iostream> #include<cstring> using namespace std; __int64 a[6000]

HDU 2177 取(2堆)石子游戏 威佐夫博弈

题目来源:HDU 2177 取(2堆)石子游戏 题意:中文 思路:判断是否是必败态就不说了 做过hdu1527就知道了 现在如果不是必败态 输出下一步所有的必败态 题目要求先输出两堆都取的方案 首先 a = b 直接2堆取完 a != b 因为bi = ai+i 现在知道ak 和 bk 那么 k = bk-ak 得到k 求出 aj 和 bj 如果ak-aj == bk-bj && ak-aj > 0(aj, bj)是必败态 输出aj bj 然后是只取一堆的情况 假设a不变 求出对应的

HDU 1058 Humble Numbers &amp;&amp; NOJ 1420 丑数 (数位dp)

Humble Numbers                          Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)                                          Total Submission(s): 18555    Accepted Submission(s): 8080 Problem Description A numb

HDU 1058 Humble Numbers (dp+打表)

先是想筛法素数表啊,然后1~2000000000枚举打表啊,结果越想越不对. 后来想到唯一分解定理,可是怎么实现呢..果然还是需要努力啊.. 研究了discuss代码,码之~ ~~~~ dp的思想,若dp[i]是Humble Numbers,那么dp[i]*2,dp[i]*3,dp[i]*5,dp[i]*7都将是Humble Numbers. 所以只需要注意连续性便好了. #include<cstdio> #include<algorithm> #include<cmath&

HDU 1058 Humble Numbers (打表)

题目链接:HDU 1058 Humble Numbers 题意:一些数他们的素数因子只有2,3,5,7.求这些数. 因为这些数的因子只可能是2,3,5,7.所以通过2,3,5,7这个四个数构造这个数列,这个数列靠后的数必定是前面的数乘上2,3,5,7得到. AC代码: #include<stdio.h> #include<set> #define ll __int64 using namespace std; set<ll> s; set<ll>::iter