【问题标题】:C++ : Trailing zeroes in array multiplicationC ++:数组乘法中的尾随零
【发布时间】:2016-10-13 06:46:34
【问题描述】:

给定一个数组 A,我必须将数组的所有元素相乘。由于数字可以达到 10^9 ,因此我必须找到产品的尾随零。我做了以下事情:

int ans= 0; // to count no of trailing zeroes 
 for(long int i =0; i<n ; i++) // n can be very large(upto 10^5)
 { 
    long long int p=1;
   p=p*a[i];
  while (p2℅10 ==0)
   { ans++;
     p=p/10;
    }
 }

计算2个数的函数如下。我用 5 替换了 2 来计算 5 的数量。

Int nm2(long long a)
{
  Int b=0;
  while(a℅2==0){
    a=a/2;
     b++;
    }
  return b;
  }

Int p2=0,p5=0;
For(long long i=L;i<R;i++)
 { 
   p2 += nm2(a[i]);
   p5 += nm5 (a[i]);
  }
 Int ans += min(p2,p5); // storing no of zeroes every time I multiply elements of array from Index L to Index R of array a[].

我该如何改进它?或者有没有其他不同的方法可以更快地计算它。请帮帮我。

【问题讨论】:

  • 这对我来说似乎是最有效的方法。转变比分裂快,但我看不到在这里利用它的方法。我个人认为你已经做到了,我期待看到其他人怎么说。好问题!
  • FWIW,如果你真的关心效率,stackoverflow.com/questions/12356442/binary-divisibility-by-10;也可以在这里看到:stackoverflow.com/questions/7070346/… BTW,这个缩进和你在实际代码中使用的一样吗?
  • @vaxquis 这个方法不会很长吧?将 long long 转换为二进制,然后进行那些位操作,然后计算零。 ?我不好,但似乎很漫长。
  • 代码有严重问题。首先,如果您的任何 a[i] 为 0,您的代码将进入无限循环。其次,乘以这么多整数保证溢出。我想说在寻求建议之前,你应该努力提高问题的资格。
  • std::div 将同时进行取模和除法

标签: c++ arrays count multiplication zero


【解决方案1】:

这更多的是关于数论,而不是关于除法的细节。这就是我会做的事情

int fives = 0;
int twos = 0;

for (int i=0; i<n; i++) {
    fives += countFives(a[i]);
    twos += countTwos(a[i]);
}

int trailingZeros = fives > twos ?  twos : fives; 

countTwos 和 countFives 这两个函数非常简单,可以分别计算给定输入值的 2 和 5 因子的数量。

计算尾随零数量的行是基于这样一个事实,即每个尾随零必须恰好是由于一个因子 2 和一个因子 5。如果您的 2 多于 5,它们将不会贡献任何额外的零,反之亦然。所以尾随零的数量等于两个计数中较小的一个。

【讨论】:

  • 我一开始就是这么做的。但是对于长数字,答案是错误的。尽管在最后一次乘法之前,数组中的一些元素已更新,但每次在数组中进行更新时,我都会更新 2 和 5 的数量。这就是为什么我必须进行除法,但这样做会超出时间限制。
  • 你能给我一个例子,我的算法给出的结果不正确。我确信这是正确的。并不意味着傲慢,但每个尾随零必须是由于 10 = 2*5 的因子,因此尾随零的数量等于“匹配”5 因子的 2 个因子的数量。
  • 你能发布计算 2 和 5 因子的算法吗?这样我就可以看到你在做什么?
  • @samthornton 你数到二是正确的。问题是你如何使用结果。请出示完整的代码。
  • @user58697 关于 2(或 5)的计数因子是正确的。一定是其他问题。
【解决方案2】:

当你处理非常大的数字时,这不就是科学记数法吗?

不知道为什么需要尾随零,但 std::scientific 可能会帮助您表达非常大的数字。

【讨论】:

  • 不,我只需要尾随零的数量。
  • 将数字转换为字符串,从末尾开始计数。或将结果打印到文件中。然后在将它们存储在文件中时对其进行计数。
  • 答案将有超过 18 位数字,因此每次存储这个大答案并多次执行此操作会非常忙碌且缓慢。所以这就是为什么我尝试使用 2 和 5 的数量。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-06
  • 1970-01-01
  • 2017-12-29
  • 2018-11-06
  • 1970-01-01
  • 2022-11-10
相关资源
最近更新 更多