相乘和比较大数字
Multiplying and comparing big numbers
我有这个问题:有K行N个数字(32位)。我必须选择数字乘积最大的那条线。
主要的问题是N可以达到20。我正试图用对数来做这件事:
ld sum = 0, max = 0;
int index = 0;
for(int i = 0; i < k; i ++) { // K lines
sum = 0, c = 0;
for(int j = 0; j < n; j ++) { // N numbers
cin >> t;
if(t < 0)
c++; // If the number is less than 0 i memorize it
if(t == 1 || t == -1) { // if numbers = 1 OR -1
sum += 0.00000001; // Because log(1) = 0
if(t == -1)
c ++;
}
else if(t == 0) { // if some number is equal to zero then the sum is = 0
sum = 0;
break;
}
else {
sum += log10(fabs(t));
}
}
if(c % 2 == 1) // if c is odd than multiply by -1
sum *= -1;
if(sum >= max) {
max = sum;
index = i;
}
if((sum - max) < eps) { // if sum is equal to max i'm also have to choose it
max = sum;
index = i;
}
}
cout << index + 1 << endl;
该程序适用于50%的测试用例。有没有一种方法可以优化我的代码?
在t=-1的情况下,将c递增两次。
如果您想避免bignum库,您可以利用它,如果将b1
和b2
位数相乘,则结果为b1+b2
位长
-
所以只需将一行中所有被乘数的位计数相加
- 并进行比较
-
记住一些阵列中的结果
int bits(DWORD p) // count how many bits is p DWORD is 32bit unsigned int { DWORD m=0x80000000; int b=32; for (;m;m>>=1,b--) if (p>=m) break; return b; }
-
index根据递减的结果位计数对行进行排序
- 如果排序后的第一个位计数也是最大值,那么它的行就是答案
- 如果您有多个最大值(多个行具有相同的位计数并且也是最大值)
- 只有这样你才能把它们相乘
现在乘法
- 你知道应该同时乘以所有的最大值
- 每次所有子结果都可以被同一素数整除
- 按它来划分
- 这样,结果将被截断为更少的位数
- 所以它应该适合64位值
- 您应该检查最大值为sqrt的素数
- 当您的最大值为32位时,请检查最高可达65536的素数
- 所以你可以制作一个素数的静态表来检查,以加快速度
- 检查素数大于实际子结果也是没有意义的
- 如果你知道怎么做,那么埃拉托斯特尼的Sieves可以极大地加快速度
- 但您需要跟踪每次除法后的索引偏移量,并使用周期性筛选表,这有点复杂,但可行
- 如果你不检查所有素数,只检查几个选定的素数
- 那么结果仍然可能溢出
- 所以你也应该处理它(抛出一些错误或其他什么)
- 或者将所有子结果除以某个值,但这可能会使结果无效
另一种乘法方法
- 也可以按值对被乘数进行排序
- 并检查是否在所有最大行中都存在一些
- 如果是,则将其更改为一个(或从列表中删除)
- 这可以与前面的方法相结合
二进制乘法
- 你可以自己做bignum乘法
- 结果是最大20*32=640位
- 所以结果将是无符号整数的数组(位宽8,16,32…随便你喜欢)
- 您也可以将数字作为字符串处理
- 关于如何在C中快速精确地计算bignum平方,请看这里++
- 它还包含乘法方法
- 这里是基于NTT的C中的Schönhage-Strassen乘法++
- 但对于像你这样的小数字来说,速度会慢一些
- 最后你需要比较结果
- 因此,与MSW和LSW相比,哪一条线中的数字更大是最大线
- (MSW是最高有效词,LSW是最低有效词)
我认为这一行肯定是错的:
if(c % 2 == 1) // if c is odd than multiply by -1
sum *= -1;
如果你的乘积在[0,1]的范围内,那么它的对数将为负,这将使它为正。我认为你应该把它分开。
相关文章:
- 比较并显示使用最小值(a,b)和最大值(a、b)升序排列的4个数字
- C++通过数字比较两个数字
- 如果相同的数字重复,如何比较流中的数字
- 使用三个数字比较器进行排序
- 如何实现通用比较?(用于数字和字符串)
- 数字之间的比较
- 如果堆栈在数字较低的地址增长,为什么指针比较会逆转这种情况?
- 如何将字符与数字进行比较?C++
- sort() 方法 c++ 中的比较器函数.为大量数字获得不同的解决方案
- 比较推送数据(100 万个数字)在 std::vector 中预先调整大小和没有
- 将数字与数字数组进行比较
- 在没有比较运算符的情况下查找 2 个数字之间的最小值
- 计数交换/比较合并排序算法的数字
- 比较二维数组中的数字时的无限循环
- C++ 比较 2 个不同列表中的值以使用 2 for 循环摆脱重复的数字。无法正确检测重复项
- c++ 输入一个数字来确定其他数字,然后比较它们
- 如何将计数器添加到气泡排序中以计数数字比较
- 两种数字比较方法中哪一种更有效
- 无法获得如果(数字== 1)比较工作
- 数字比较比字符串比较快