函数approximate和函数nearestZero是用来求最接近0的算法。函数nearestTot是用来求最接近t的算法,算法思想仍然是递归的分治算法,和求和最小子向量的算法很类似,复杂度为O(nlogn)。没有想出来更好的解决方案。
#include<iostream>
#include<algorithm>
usingnamespace std;
int nearestZero(intA[],int n)
{
int*sum=newint[n];
sum[0]=A[0];
for(int i=1;i<n;i++)
sum[i]=sum[i-1]+A[i];
sort(sum,sum+n);
intresult=sum[0]-sum[1];
for(int i=2;i<n;i++)
{
result=min(result,sum[i]-sum[i-1]);
}
returnresult;
}
int nearestTot(intA[],int n,intt)
{
if(n==1)
returnA[0];
intmid=n>>1;
intleft=mid-1,right=mid;
intmidSum=A[left]+A[right],result=A[left--]+A[right++];
while(left>=0|| right<n)
{
intleftValue=left>=0?A[left]:INT_MAX>>1,rightValue=right<n?A[right]:INT_MAX>>1; //此处右移一位的原因是:如果不右移,则数据太大,导致下面的abs(result+leftValue-t)有可能出现负值,如result-t==1,则会出现这种情况,因此为了避免这种情况就都右移了一位。
if(abs(result+leftValue-t)<abs(result+rightValue-t))//如果加上左边值更接近t则加左边
{
result+=leftValue;
left--;
}
else//否则加右边
{
result+=rightValue;
right++;
}
if(abs(result-t)<abs(midSum-t))
{
midSum=result;
}
}
if(abs(midSum-t)<abs(nearestTot(A,mid,t)-t))
{
if(abs(midSum-t)<abs(nearestTot(A+mid,n-mid,t)-t))
return midSum;
else
{
return nearestTot(A+mid,n-mid,t);
}
}
else
{
if(abs(nearestTot(A,mid,t)-t)<abs(nearestTot(A+mid,n-mid,t)-t))
return nearestTot(A,mid,t);
else
{
return nearestTot(A+mid,n-mid,t);
}
}
}
int approximate(int* pArry,int len)
{
int * cum =0;
int *realarry =new int[len+ 1];
realarry[0] = 0;
cum = realarry + 1; //cum[-1] = 0
//累计pArry[0....i]的和存放于cum[i]中
for (int i = 0; i < len; i++)
{
cum[i] = cum[i - 1] + pArry[i];
}
sort(cum, cum + len); //对cum排序
int iMin =cum[1] - cum[0];
for (int k = 1; k < len; k++)
{
iMin = min(iMin, cum[k] - cum[k -1]); //返回相邻两个元素差值最小的
}
delete[]realarry;
returniMin;
}
int main()
{
intA[]={-1,2,3,-5,50,10,-8};
cout<<nearestTot(A,7,40);
system("pause");
return 0;
}