算法 - 查找纯数字

时间:2013-01-29 13:59:38

标签: c algorithm optimization

  

说明

     

当且仅当m可以时,正整数m被称为纯数   表示为素数p的q次幂(q> = 1)。在这里你的工作很简单,   对于给定的正整数k,找到第k个纯数。

     

输入:

     

输入包含多个测试用例。对于每个测试用例,它   包含正整数k(k <5,000,000)。处理到文件结束。

     

输出:

     

对于每个测试用例,在一行中输出第k个纯数。如果   答案大于5,000,000,只输出-1。

     

示例输入:

     

1

     

100

     

400000

     

示例输出:

     

2

     

419

     

-1

原始页面:http://acm.whu.edu.cn/learn/problem/detail?problem_id=1092

任何人都可以就此解决方案给我一些建议吗?

2 个答案:

答案 0 :(得分:4)

你已经找到了所有纯数字,这是棘手的部分。对小于500万的那些进行排序,然后在结果数组中依次查找每个输入。

为了优化您需要有效地查找高达500万的所有素数(在问题描述中注意q >= 1:每个素数都是纯数),您将需要使用某种筛(筛子筛) Erathosthenes会做,查阅它。

你可能会调整筛子以留下素数的力量,但我预计不需要很长时间就可以正常筛选然后将权力重新投入。你只需要计算质数p的幂,其中p <= 500万的平方根,即2236,所以与寻找素数相比,这不应该花费很长时间。

用筛子找到数字后,您不再需要对它们进行排序,只需将筛选后的标记值复制到新数组即可。

现在看看你的实际代码:你的QuickSort例程是可疑的。它对已经排序的数据执行得很糟糕,并且您的数组将在其中运行已排序的数字。请尝试qsort,或者如果你应该自己做所有事情,那么你需要阅读快速排序的数据透视选择。

答案 1 :(得分:0)

尝试以下方法:

static void Main(string[] args)
{

    int max = 5000000;
    int[] dp = new int[max];
    for (int i = 2; i < max; i++)
    {
        if (dp[i] == 0)
        {
            long t = i;
            while (t < max)
            {
                dp[t] = 1;
                t *= i;
            }
            int end = max / i;
            for (int j = 2; j < end; j++)
                if (dp[i * j] == 0)
                    dp[i * j] = 2;
        }
    }

    int[] result = new int[348978];
    int pointer = 1;
    for (int i = 2; i < max; i++)
    {
        if (dp[i] == 1)
            result[pointer++] = i;
    }
}

以数字“1”标记纯数字。 由于“2”标记为非纯(素数)。

对于每个输出检查数组范围,如果它在输出结果[索引] 内,如果不输出应为-1。