码迷,mamicode.com
首页 > 其他好文 > 详细

找丑数

时间:2017-10-18 09:57:40      阅读:201      评论:0      收藏:0      [点我收藏+]

标签:span   scan   丑数   cout   pre   name   技术   alt   algo   

额,刚开始比较naive,直接用stl大法,结果T了

#pragma GCC optimize(2)
#include<cstdio>
#include<iostream>
#include<queue>
#include<set>
#include<vector>
#define ll long long
using namespace std;
ll n,m,val,zhi,tot,ce[123123];
priority_queue <ll , vector <ll> , greater<ll> > q;
set <ll> s;
int main(){
    scanf("%lld%lld",&n,&m);
    for(int i=1;i<=n;i++)
    {
        scanf("%lld",&val);
        ce[i] = val;
        s.insert(val);
        q.push(val);
    }
    while(1)
    {
         val = q.top();
         q.pop();
         tot++;
         if(tot == m)
         {
             cout << val;
             return 0;
         }
         for(int i=1;i<=n;i++)
         {
             zhi = val * ce[i];
             if(!s.count(zhi))
             {
                 s.insert(zhi); 
                 q.push(zhi); 
            }
         }
    }
    
}

 

然后把优先队列改成手写堆,set该做map,继续T。。。QAQ。。。

 

#pragma GCC optimize(2)
#include<cstdio>
#include<map>
#define ll long long
using namespace std;
ll n,m,val,zhi,tot,ce[1231203];
ll dui[1001000];
map <ll,int> s;

inline void insert(ll val)
{
    dui[++tot] = val;
    ll k = tot;
    while(k > 1 && dui[k] < dui[k >> 1])
    {
        swap(dui[k] , dui[k >> 1]);
        k >>= 1;
    }
}

inline void del()
{
    dui[1] = dui[tot--];
    bool k;
    ll p = 1;
    while(p * 2 <= tot)
    {
        if(p * 2 == tot) k = 0;
        else k = dui[p << 1] > dui[p << 1 | 1] ? 1 : 0;
        if(dui[p] > dui[p * 2 + k])
        {
            swap(dui[p] , dui[p * 2 + k]);
            p = p * 2 + k;
        }
        else break;
    }
}

int main(){
    scanf("%lld%lld",&n,&m);
    
    for(int i=1;i<=n;++i)
    {
        scanf("%lld",&val);
        ce[i] = val;
        insert(val);
        s[val] = 1;
    }
    
    for(int j=1;j <= m;++j)
    {
        if(j == m)
        {
            printf("%lld",dui[1]);
            return 0;
        }
        val = dui[1];
        del();
        for(int i=1;i<=n;++i)
        {
            zhi = val * ce[i];
            if(!s.count(zhi))
            {
                insert(zhi);
                s[zhi] = 1;
            }
        }
    }
}

 

最后做了一些操作就可以过了,不过很妙啊,看看代码应该就懂了吧。

#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
ll n,m,val,zhi,tot,ce[131203];
struct st{
    ll val;
    int ji;
}dui[8001000];

inline void insert(st t)
{
    dui[++tot] = t;
    ll k = tot;
    while(k > 1 && dui[k].val < dui[k >> 1].val)
    {
        swap(dui[k] , dui[k >> 1]);
        k >>= 1;
    }
}

inline void del()
{
    dui[1] = dui[tot--];
    bool k;
    ll p = 1;
    while(p * 2 <= tot)
    {
        if(p * 2 == tot) k = 0;
        else k = dui[p << 1].val > dui[p << 1 | 1].val ? 1 : 0;
        if(dui[p].val > dui[p * 2 + k].val)
        {
            swap(dui[p] , dui[p * 2 + k]);
            p = p * 2 + k;
        }
        else break;
    }
}

int main(){
    scanf("%lld%lld",&n,&m);
    
    for(int i=1;i<=n;++i)
    {
        scanf("%lld",&val);
        ce[i] = val;
        st a;
        a.val = val;
        a.ji = i;
        insert(a);
    }
    
    for(int j = 1;j <= m;++j)
    {
        if(j == m)
        {
            printf("%lld",dui[1].val);
            return 0;
        }
        val = dui[1].val;
        int ka = dui[1].ji;
        del();
        for(int i=ka;i<=n;++i)
        {
            zhi = val * ce[i];
            st a;
            a.val = zhi;
            a.ji = i;
            insert(a);
        }
        
    }
}

技术分享

 

找丑数

标签:span   scan   丑数   cout   pre   name   技术   alt   algo   

原文地址:http://www.cnblogs.com/kczno1fans/p/7685011.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!