分拆数组技巧应用

给你一个数组A[1..n],请你在O(n)的时间里构造一个新的数组B[1..n],使得B[i]=A[1]*A[2]*...*A[n]/A[i]。你不能使用除法运算。

思路1:题目中说明,不能用除法,那一定是在相乘的时候,省略那一项,然后时间复杂度要0(n),就不能两层循环,而是要利用前面的相乘信息来降低复杂度。

算法:相似的分拆技术在数组题中。线性时间构造两个新数组,从开始遍历相乘 T1[0] =1,T1[i]=T[i-1]*A[i-1]  ;而 T2从后往前遍历相乘 T2[len-1] =1,T2[i] = T2[i+1]*A[i+1] ,这样B[i] = T1[i]*T2[i]

思路2:不能用除法,可以想到,用对数将乘法,转为减少,这种方法理论上可行正确,但是求log出来在计算机上有误差,不能得到精确小数。

以下是实现C++代码实现的两种思路:

//思路1
void special_mult1(int *A,int *B,int len)
{
    int i;
    int *T1 = new int[len];
    T1[0] = 1;
    for(i=1;i<len;i++)  //从前往后累乘,滞后一个
        T1[i] = T1[i-1]*A[i-1];
    B[len-1] = 1;

    for(i = len-2;i>=0;i--) //从后往前累乘
        B[i] = B[i+1]*A[i+1];

    for(i =0;i<len;i++)  //前后合并
        B[i] = B[i]*T1[i];

    delete T1;
}
//思路2
void special_mult2(int *A,int *B,int len)
{
    int i;
    long long mut_result =1 ;
    for(i =0;i<len;i++)
        mut_result *=A[i];
    for (i=0;i<len;i++)  //这种方法理论上可行,但是求log出来在计算机上有误差,不能得到精确小数
    {
        B[i] =pow((long double)10,log10((long double)mut_result) - log10((long double)A[i]));
    }
}

例子:int A[5]={1,2,3,4,5};

可以看到,方法2计算的结果存在误差,是不正确的。

时间: 2024-08-07 13:20:48

分拆数组技巧应用的相关文章

平面分拆的 Macmahon 公式

首先看一个计数问题:一个边长为 $a\times b\times c$ 的平行六边形,每个内角都是 120 度.用边长为 1 的菱形去覆盖,有多少种不同的方法? 比如下图就是一种: 我们从上方俯视这张图(虽然这是一个平面图形,但是我们想象在空间中鸟瞰它),发现它很像是在墙角堆箱子:在一个边长为 $a\times b\times c$ 的长方体空间中堆放若干形状为单位正方体的 "箱子".不仅如此,箱子堆放的规则是有限制的:紧贴墙角处的那一摞箱子最高,从墙角向外,箱子的高度是递减的.这个规

组合数学漫游奇境记:Schur 多项式,Hook 长度公式,Macmahon 平面分拆公式

Young 表上的组合学是代数组合学中最奇妙的部分,与表示论,统计力学,概率论有着丰富而深刻的联系.这篇文章将从几个有趣的问题开始,带领大家走进这个美丽的领域.所需要的预备知识很少,学过线性代数即可,但是要真正领略其中风光,数学上的成熟是必不可少的. 需要事先剧透的是,本文要证明的几个定理绝非泛泛,它们都是代数组合学中的著名结论. 先来看几个问题: 有 $m$ 位总统候选人参加大选,他们每个人分别有 $\lambda_1,\ldots,\lambda_m$ 位支持者(假定选民只投票给他支持的候选

叠式的常规性转行分拆规则

限于版面的横向尺寸,对超长的叠式可以分拆转行.一般包括常规性的转行分拆.积分式的转行分拆.分子或分母的转行分拆和根式的转行分拆等几种方法.叠式转行分拆也有一定的规则,不能乱拆,否则要造成数据运算错误的后果!下面我们来具体讲解MathType中叠式的常规性转行分拆规则: 叠式的常规性转行分拆原则,与单行数式相同.但对于一些特殊的数学符号,不能与其后边的被运算对象分拆.如以下等式: 不能分拆转行成: 又如以下等式: 不能分拆成: 累次求和或累次积分等的叠式,原稿是一行写下的,最好不要转行,假如限于版

hdu2098分拆素数和(素数+暴力)

分拆素数和 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 48614    Accepted Submission(s): 21227 Problem Description 把一个偶数拆成两个不同素数的和,有几种拆法呢? Input 输入包含一些正的偶数,其值不会超过10000,个数不会超过500,若遇0,则结束. Output 对应

Python3+将2声道音频,分拆成1声道

现在是将双声道的音频分拆成单声道的. 同理可以将多声道的音频文件,转为1声道的音频文件. 注意新形成的音频文件的rate,需要与原音频的相同. import os import wave import numpy as np import pyaudio file1 = os.path.join(os.path.abspath(os.path.dirname(os.path.dirname(__file__))), '音频文件/执迷不悟.wav') f = wave.open(file1, "r

分拆素数和 埃氏筛法

分拆素数和 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 2098 Description 把一个偶数拆成两个不同素数的和,有几种拆法呢? Input 输入包含一些正的偶数,其值不会超过10000,个数不会超过500,若遇0,则结束. Output 对应每个偶数,输出其拆成不同素数的个数,每个结果占一行. Sample Input 30

整数分拆的非递归程序

#include<stdio.h> void print_partition(int n) { int i=1; int m=1; int h=1; int t,r; int a[n+1]; for(;i<n+1;++i)a[i]=1; a[1]=n; printf("%d\n",a[1]); while(a[1]!=1) { if(a[h]==2) {a[h--]--;m++;} else { r=--a[h]; t=m-h+1; while(t>=r){a[

Winform开发框架中实现多种数据库类型切换以及分拆数据库的支持 - 伍华聪

在很多应用系统里面,虽然一般采用一种数据库运行,但是由于各种情况的需要,可能业务系统会部署在不同类型的数据库上,如果开发的系统能够很方便支持多种数据库的切换,那可以为我们减少很多烦恼,同时提高系统的适应性和强壮型.还有一种情况,由于业务数据库的不断膨胀或者方便数据库的切割隔离,有时候也会把不同的业务数据库进行分拆,如权限提供数据库,客户关系管理数据库,工作流程数据库,企业营运数据库等等,因此在一个系统里面,同时使用2个或者以上的数据库的情况也是有的.针对这两种情况,本文介绍在我的Winform开

研究理财业务改革 目前无分拆上市计划

研究理财业务改革 目前无分拆上市计划 中国证券网讯(记者 陈天弋)光大银行(601818,股吧)3月17日晚间公告,近日,有媒体报道引述有关公司的研究报告,称光大银行等上市银行将分拆理财等业务(成立独立子公司),并谋求分拆资产上市.公司特澄清如下: 公司按照监管机构的政策导向,正在研究推进理财业务改革试点,包括设立独立子公司.该事项尚需履行公司内部审议决策程序,以及报请监管机构审批,存在不确定性.该事项不会对公司未来的经营业绩产生重大影响,公司目前亦无分拆资产上市的相关工作计划. 各位代表: 受