说明
当且仅当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
任何人都可以就此解决方案给我一些建议吗?
答案 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。