【问题标题】:Count number of non-prime pairs that when multiplied form a given number N,计算从给定数 N 相乘时的非质数对的数量,
【发布时间】:2017-04-03 05:24:41
【问题描述】:

形成N的非素数对是2个不同的非素数,其中数字的乘积为N。

1

例如 对于 N = 24,有 2 个好对(构成 N 的非质数对)(4,6), (1,24), 但是 (2,12), ( 3,8) 不好。

注意:对于任意 2 个数字 a 和 b pair(a,b) = pair(b,a)。

还有一个条件,如果这个数是一个特殊数,那么 output = -1 否则计算非素数的个数。

如果数可以表示为三个素数的乘积,则称为特殊数。示例:12 是一个特殊的数字,因为 12=2*2*3;

我尝试了使用 https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes 的蛮力方法, 这需要 O(N*log(log(N))。

“除了蛮力还有什么更优化的解决方法吗?”

任何想法都会受到赞赏。

提前致谢。

【问题讨论】:

  • 为了这些目的,大部分时间,最好的解决方案就是计算模数。准备一个 char 向量,如果是素数,则设置标志,因为 sqrt(N)。比从 sqrt(N) 开始使用 Modulus 暴力破解它,当你找到一个除数时,检查它是否是素数。
  • 欢迎来到 Stack Overflow!请查看我们的SO Question Checklist 以帮助您提出一个好问题,从而得到一个好的答案。
  • 您链接到的维基百科文章说“埃拉托色尼筛是找到所有较小素数的最有效方法之一。”它还说“在随机存取机器模型中计算所有低于 n 的素数的时间复杂度是 O(n log⁡ log n) 操作”。所以如果你关心效率,我认为你不需要做得更好来找到素数。
  • @OleV.V.非常感谢。

标签: java arrays algorithm time-complexity primes


【解决方案1】:

首先,Eratosthenes 的筛子是 O(N*log(log(N))列出所有低于或等于 N 的素数(当 well implemented 时)。

第二:假设您将您的数字分解为具有多重性的 Q 素数,如果不进行筛选,最坏的情况是 O(sqrt(N)) 的过程(最坏的情况:您的数字是素数)。所以你有一张地图:

  • p0 -> 多重性 m0
  • p1 -> 多重性 m1
  • ...
  • pQ -> 多重性 mQ

至少乘以 2 个质因数得到多少个除数?

嗯,会有 m0*m1*...mq [更正这里]。为什么?好吧,准备一个由每个因子的幂生成的所有除数的列表(包括 pi0==1),但删除具有 @ 幂的除数987654324@。

  • {1, p0, p02, ...p0m0} 是 m0 生成除数的方法,除 p0 外具有 p0 的幂
  • {1, p1, p12, ...p1m1} 是 m1 生成除数的方式,除 p1 外具有 p1 的幂
  • ...
  • {1, pQ, p1Q, ...p1mQ} 是mQ使用pQ 的幂生成除数的方法

具有非素因数的所有组合的数量(因为1 已经包含在每个集合中,并且每个素因数本身被排除在外)将是上述所有子集的笛卡尔积的基数 - 因此产品个别基数,因此m0*m1*...mq


代码 - Java

import java.util.HashMap;
import java.util.Map;

class Example {

  static void factor(long N, Map<Long, Short> primesWithMultiplicity) {
    // some arg checking and trivial cases
    if(N<0) N=-N;
    if(0==N) {
       throw new IllegalArgumentException(
         "Are you kidding me? Every number divides 0, "+
         "you really want them all listed?"
       );
    }
    if(1==N) {
      primesWithMultiplicity.put(1L,(short)1);
      return;
    }

     // don't try divisors higher than sqrt(N), 
    // if they would have been detected by their composite-complement 
    for(long div=2; div*div < N; ) {
      short multiplicity=0;
      while((N % div)==0) {
        multiplicity++;
        N /= div; // reduce N
      }
      if(multiplicity>0) {
        primesWithMultiplicity.put(div, multiplicity);
      }
      div+= (div == 2 ? 1 : 2); // from 2 to 3, but then going only on odd numbers
    }
    // done.. well almost, if N is prime, then 
    // trying to divide up to sqrt(N) will lead an empty result. But,
    // in this case, N will still be at original value (as opposed 
    // to being 1 if complete factored)
    if(N>1) {
      primesWithMultiplicity.put(N, (short)1);
    }
  }

  static int countDistinctCompositePairs(long N) {
    HashMap<Long, Short> factoringResults=new HashMap<>();
    factor(N, factoringResults);
    int ret=1;
    for(short multiplicity : factoringResults.values()) {
      ret*=multiplicity;
    }
    return ret/2;
  }

  static public void main(String[] args) {
    System.out.println(countDistinctCompositePairs(24));
  }
}

【讨论】:

  • @user5956891 欢迎(顺便说一句,感谢通常通过支持答案和/或如果它确实回答了您的问题,则接受它来表达)
  • @user5956891 代码已更正(我之前有一些讨厌的错误)
  • 当我输入 N=24 时,Sir 代码给出的结果是 6 而不是 2。
  • Colomithci 先生,存在不兼容类型 int 无法转换为 Long 的问题。
  • "当我输入 N=24 时,Sir 代码给出的结果是 6 而不是 2。"嗯……让我想一想。
【解决方案2】:

由于您没有提到约束,我假设 1

这是相同的代码。

int a[1000001];
a[1]=1;
for(int i=2;i*i<1000001;i++)
{
    if(a[i]==0)
    {
        for(int j=2*i;j<1000001;j+=i)
        a[j]=i;
    }
}

现在如果数字是素数,你的答案是 0。

if(a[n]==0) 
cout<<'0';

如果它是半素数(两个素数的乘积),你的答案将是 1。

if(a[n/a[n]]==0)
cout<<"1";

如果是特殊的话

int x=n/a[n];
if(a[x/a[x]]==0)
cout<<"-1";

如果它不满足任何上述条件,则计算所有非素除数。

int c=0;
for(int i=1;i*i<n;i++)
    {
        if(n%i==0)
        {
            if(a[i]!=0&&a[n/i]!=0)
            c++;

        }
    }

希望这会有所帮助!

【讨论】:

  • 当 N=12 然后输出 = -1 但您的代码给出 -11 而不是 -1 时,请尝试修复它;
  • 其实问题是当
  • 实际上的问题是当if(a[x/a[x]]==0) { cout&lt;&lt;"-1"&lt;&lt;endl; }之后它不应该计算这个代码部分int c=0; for(int i=1;i*i&lt;n;i++) { if(n%i==0) { if(a[i]!=0&amp;&amp;a[n/i]!=0) c++; } } cout&lt;&lt;c&lt;&lt;endl;这为什么它给出-11,-1表示特殊素数,第二个1因为计算非素数
  • 我明白了。非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-04-28
  • 1970-01-01
  • 1970-01-01
  • 2015-06-14
  • 1970-01-01
  • 2013-09-18
  • 2011-05-27
相关资源
最近更新 更多