鉴于 1 - 索引数组 A 的大小 N ,任何距离 此 i 的 2 指数由 | i-j | 给出。现在,根据这些信息,我需要找到每个指数 i (1≤i≤N),索引 j ,这样< strong>1≤j≤N, i≠j , GCD(A [i],A [j])> 1 。
如果索引 i 有多个这样的候选者,则必须找到索引 j ,以便 i 和 j 很少。如果仍有多个候选者,请打印满足上述约束的最小 j 。
实施例: 数组(A) 2 3 4 9 17
输出:3 4 1 2 -1
注意:数组大小可以大到2 * 10 ^ 5。 每个数组元素的最大值可以是2 * 10 ^ 5,最小值是1。
我应该能够在最多1秒内计算出来。
这是我的代码,但超出了时间限制。有没有办法优化它。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class GCD {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine().trim());
int[] a = new int[n+1];
StringBuilder sb =new StringBuilder("");
String[] array = br.readLine().trim().split(" ");
for(int i=1; i<=n; i++){
a[i] = Integer.parseInt(array[i-1]);
}
int c,d;
l1: for(int i=1; i<=n; i++){
c = i-1;
d = i+1;
while((c>0||d<=n)){
if(c>0){
if(GCD(a[i],a[c])>1){
sb.append(c+" ");
continue l1;
}
}
if(d<=n){
if(GCD(a[i],a[d])>1){
sb.append(d+" ");
continue l1;
}
}
c--;
d++;
}
sb.append("-1 ");
}
System.out.println(sb);
}
static long GCD(int a, int b){
if(b==0)
return a;
return GCD(b, a%b);
}
}
答案 0 :(得分:0)
要在1秒内运行,您的算法应为θ(N)或θ(N * log(N)),N <2 * 10 ^ 5。一种方法是:
答案 1 :(得分:0)
你知道问题可以在一秒钟内解决。你知道这个数组可以有200,000个元素。将200,000个元素与200,000个元素进行比较需要进行400亿次比较。如果你很幸运,你的计算机每秒可以完成30亿次操作。您会发现,将200,000个元素与200,000个元素进行比较是行不通的。 (这将发生在所有数组元素都等于1的简单情况下)。因此,优化您的代码无济于事。
因此,请将您的思维从提出问题的方式移开。它要求找到j使得gcd(a [i],a [j])!= 1.它真正意味着找到j使得[j]具有与[i]共同的素因子。并且j需要是最大的j&lt;我或最小的j>一世。
数字很小,不到200,000。因此,您可以非常快速地找到a [i]的所有不同素因子。
首先你创建一个数组“index”:对于每个素数p <= 200,000,index [p]是你检查过的具有素数因子p的最后一个数组元素a [j]的索引j,如果你没找到,则为-1。您还可以创建一个数组“解决方案”:对于您检查的每个i,它包含到目前为止最接近的数字或-1。
遍历数组i = 1到n:对于每个a [i],找到所有素数因子。对于每个因子p:如果j = index [p]&gt; 0然后a [j]也可以被p整除,所以gcd(a [i],a [j])&gt; 1.做到这一点,你得到最大的j&lt;我用gcd(a [i],a [j])&gt; 1.当您找到素数因子时,还要更新数组索引。
但是如果你发现a [i]和[j]有一个共同因子,那么你为j存储的解决方案可能是错误的,因为它只考虑小于j的索引,所以也更新解决方案。伪代码:
Create array "index" filled with -1.
Create array "solution" filled with -1.
for all i
for all prime factors p of a [i]
let j = index [p]
index [p] = j
if j >= 0
if solution [i] = -1
solution [i] = j
else if j > solution [i]
solution [i] = j
if solution [j] = -1
solution [j] = i
else if solution [j] < j && i-j < j - solution [j]
solution [j] = i
print solution
你可以看到,具有公共因子的数组元素离开多远并不重要。执行时间是素数因子的数量的非常小的倍数加上找到因子的时间,如果所有元素都是大素数,则这是最差的。所以你需要做的就是找到任何数字的所有因素&lt; 200,000,比如说3-4微秒。应该很容易。在开始之前,您可以创建一个最多500的素数表。