POJ 1338 Ugly Numbers

[成绩]
Run ID User Problem Result Memory Time Language Code Length Submit Time
6504064 weweweer9 1338 Accepted 992K 0MS G++ 2148B 2010-03-02 19:40:21
6503693 weweweer9 1338 Accepted 824K 0MS G++ 1772B 2010-03-02 18:36:01
6503581 weweweer9 1338 Wrong Answer

G++ 1427B 2010-03-02 18:19:23
[报告]
    佳哥的课件里有这道题,看到了顺便就切掉了。
    首先,忽略6503581(那个和6503693一个算法,就是它没开LONG LONG,就WA了)。
    这里有两个算法:6503693是O(NlogN)的;6504064是O(N)的;还有个O(1)的,我没写。
    O(NlogN):就是佳哥课件里的那个算法。维护一个优先队列(二叉堆),每当从队首取出一个元素,都将它的2,3,5倍数加入队列。反复此过程,当取出N个数时,最后取出的数为最后的答案。
    O(N):这个是lordxfastx告诉我的一个算法。由于O(NlogN)中每取出的数*2,都必然比它前面取出的数*2小(3,5同理)。因此,可以维护3个单调队列,分别保存*2,*3,*5的值。每次取出的数为三个单调队列中队首的最小值。由于这个算法不需要多余的交换什么的,所以就是O(N)的。
    O(1):显然——打表……(不解释)
[程序]
6503693:


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#define func(x) inline static x
#define N 9973
using namespace std;
long long h[N+1];
long long a[N+1],n;
func(void) down(long x)
{
    long long i=x,j=x<<1,ax=a[x];
    while (j<=n)
    {
        if (j<n&&a[j]>a[j+1]) j++;
        if (ax>a[j])
        {
            a[i]=a[j];
            i=j;j=i<<1;
        }else break;
    }
    a[i]=ax;
}
func(void) up(long x)
{
    long long i=x,j=x>>1,ax=a[x];
    while (j>0&&ax<a[j])
    {
        a[i]=a[j];
        i=j;j=i>>1;
    }
//    if (a[j]!=ax)
        a[i]=ax;
//    else
//    {
    //    a[i]=a[n--];
    //    down(i);
    //}
}
long m=0;
func(bool) hash(long long x)
{
    long ax=x%N;
    while (h[ax]!=0&&h[ax]!=x) ax=(ax+1)%N;
    if (h[ax]==x) return true;
    else return !(h[ax]=x);
}
func(void) insert(long long x)
{
    if (hash(x)) return;
    m++;
    a[++n]=x;
    up(n);
}
func(void) erase()
{
    a[1]=a[n--];
    down(1);
}
func(void) print()
{
    printf("%d:",n);
    for (long i=1;i<=n;i++)
        printf("%d ",a[i]);
    printf("\n");
}
func(long long) solve(long k)
{
    memset(h,0,sizeof(h));
    memset(a,0,sizeof(a));
    m=0;
    n=1;
    a[1]=1;
    long long ax;
    while (k>1)
    {
        ax=a[1];
        k--;
        erase();
        insert(ax*2);
        insert(ax*3);
        insert(ax*5);
    //    print();
    }
    //cout << m << endl;
  
posted @ 2010-03-02 19:45  为美好世界献上珂学  阅读(117)  评论(0)    收藏  举报