有效的方法来查找数字在A.P.中的所有这些三元组的数量(来自一组给定的数字)?

时间:2012-11-10 18:38:30

标签: java c++ c math

  

可能重复:
  fastest algorithm count number of 3 length AP in array

我一直致力于从CodeChef的Nov12挑战中解决以下问题。我尝试使用基本公式检查三个数字a,b,c是否在A.P.中,如果c-b = b-a,即2b = a + c。这是问题所在:

输入的第一行包含整数N(3≤N≤100000)。然后,以下行包含N个空格分隔的整数A1,A2,...,AN,它们的值介于1和30000之间(含)。

输出选择三元组的方式的数量,使得它们是算术级数的三个连续项。 实施例

输入:

10

3 5 3 6 3 4 10 4 5 2

输出: 9

说明:

以下是选择三联的所有9种方法

1:(i,j,k)=(1,3,5),(Ai,Aj,Ak)=(3,3,3)

2:(i,j,k)=(1,6,9),(Ai,Aj,Ak)=(3,4,5)

3:(i,j,k)=(1,8,9),(Ai,Aj,Ak)=(3,4,5)

4:(i,j,k)=(3,6,9),(Ai,Aj,Ak)=(3,4,5)

5:(i,j,k)=(3,8,9),(Ai,Aj,Ak)=(3,4,5)

6:(i,j,k)=(4,6,10),(Ai,Aj,Ak)=(6,4,2)

7:(i,j,k)=(4,8,10),(Ai,Aj,Ak)=(6,4,2)

8:(i,j,k)=(5,6,9),(Ai,Aj,Ak)=(3,4,5)

我使用的代码是

#include<stdio.h>
int scan() {
    int p=0;
    char c;
    c=getchar_unlocked();
    while(c<'0' || c>'9')
        c=getchar_unlocked();
    while(c>='0' && c<='9'){
        p=(p<<3)+(p<<1)+c-'0';
        c=getchar_unlocked();
    }
    return(p);
}
int main() {
    int N, i, j, k, count=0;
    N=scan();
    int a[N];
    for(i=0;i<N;i++)
        a[i]=scan();
    for(i=0;i<N-2;i++)
        for(j=i+1;j<N-1;j++)
            for(k=j+1;k<N;k++)
                if(a[k]+a[i]==2*a[j])
                    ++count;
    printf("%d\n", count);
    return 0;
 }

正如您可以看到对变量的约束,显然我们需要快速有效的算法。为了安全起见,我甚至使用了更快的I / O,但程序仍然耗尽时间。 很明显,算法效率不高,因为我使用了三个嵌套循环。另一种减少某些k的数量的方法是在找到匹配后立即打破k'循环,然后我会添加一个继续;低于++计数,这是有效的,但不再像问题那样有效。

请告诉我一些快速的算法,或者如果我可以在这里学习一些数学定理来更快地找到AP三元组。

1 个答案:

答案 0 :(得分:0)

我认为你不需要阵列。

从等式2b=a+c求解b,结果为:

b = (a + c) / 2

使用4个变量:a, b, c, and counter

  1. 通过阅读3个值来初始化a, b, c
  2. if(a + c)/ 2 == b,增加计数器,然后打印a,b,c。
  3. 换档变量:a = b,b = c。
  4. while cin&gt;&gt; c做:
  5. if(a + c)/ 2 == b,增加计数器并打印a,b,c。
  6. 移位变量:a = b,b = c;
  7. 端一段时间。
  8. 计数器的输出值。
  9. 对我来说效率很高。