找到所有对,使得x ^ 2 + y ^ 2 =< N ^ 2

时间:2017-01-23 19:58:25

标签: c algorithm

我正在尝试在C中编写一个算法,对于给定的自然数n,它会找到(x,y)对的数量x,y,其中{{1}}是整数,

  

x 2 + y 2 < = n 2

我能够通过两个for循环执行此操作,但是,这似乎不是最理想的。这个问题最有效的方法是什么?

3 个答案:

答案 0 :(得分:3)

你不需要两个循环。只需循环遍历x,然后就可以计算y,因为xn都已知。

答案 1 :(得分:3)

只需要在边界处找到点,即对于每个给定的x,最大y_max s.t. x ^ 2 + y_max ^ 2< = n。那么给定x的有趣对的数量是2 * y_max + 1。对于x = 0,我们有y_max = n。对于x> 0,我们还必须考虑具有-x的对。这导致以下代码:

int pairCnt = 2*n+1; /* pairs (0,-n), (0,-n+1), ..., (0,n) */
int n2 = n*n;
for (int x=1; x<=n; ++x)
{
   int y_max = (int)sqrt(n2-x*x);
   pairCnt += 2*(2*y_max+1); /* (+/-x,-y_max), ..., (+/-x,y_max) */
}

使用以下算法可以避免使用sqrt:

int pairCnt = 2*n+1; /* pairs (0,-n), (0,-n+1), ..., (0,n) */
int n2 = n*n;
for (int x=1, y_max=n; 1; ++x)
{
  if (y_max*y_max > n2-x*x)
    --y_max;
  if (x > y_max) break;
  pairCnt += 2*(2*y_max+1); /* (+/-x,-y_max), ..., (+/-x,y_max) */
}
int s = 2*x-1; /* side length of maximal inscribed square */
pairCnt = 2*pairCnt - s*s;

第二种算法的第一个想法是,当x增加时,y_max将最大减少1,只要y_max> x(即我们沿着圆的内部,半径为n从(0,n)开始直到我们越过第一个中位数y = x)。当我们将计数点的副本加上90°(即到目前为止发现的点数的两倍)时,我们将计算最大内切正方形内的点数两次。

这是n = 3的一种可视化。 *标记有趣集合(x*x+y*y > n*n=9)之外的对。数字标记到目前为止计算有趣集合(x*x+y*y <= n*n=9)内的对的频率。

  before loop  after loop  after doubling  result
   ----         ----         ----          ----
   432101234    432101234    432101234     432101234

 4 *********    *********    *********     *********
 3 ****1****    ****1****    ****1****     ****1****
 2 **00100**    **11111**    **22222**     **11111**
 1 **00100**    **11111**    **22222**     **11111**
 0 *0001000*    *0111110*    *1222221*     *1111111*
-1 **00100**    **11111**    **22222**     **11111**
-2 **00100**    **11111**    **22222**     **11111**
-3 ****1****    ****1****    ****1****     ****1****
-4 *********    *********    *********     *********

答案 2 :(得分:0)

如果你实现了一个函数int int_sqrt (int n),它返回sqrt(double n)的整数部分,那么你可以使用这个函数只用一个循环来处理它。但整数平方根仅存在于C ++中,因此您必须通过将结果转换为int来实现C中的一个

编辑: 这是个主意:

int x=0,result=0;
while ( (n-(x*x)) >=0){
    result += int_sqrt ( n-(x*x) ) +1;
    x++;
}

如果您接受所有整数,包括0来制作您的情侣。