题目链接:Boring Sum
题面:
5 1 4 2 3 9 0
136HintIn the sample, b1=1, c1=4, b2=4, c2=4, b3=4, c3=2, b4=3, c4=9, b5=9, c5=9, so b1 * c1 + b2 * c2 + … + b5 * c5 = 136.
解题:直接暴肯定不行。先预处理一下,将每个ai的值存在对应下标中。然后,寻找某个值时,只需遍历该值的倍数对应的vector寻找最接近的左边值和右边值。需注意的是当ai比较小的时候就直接寻找,以提高效率,这里边界设置为300。
代码:
#include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
using namespace std;
int a[100000+10];
vector <int> store[100000+10];
int main()
{
int n,tmp,maxx,b,c,p,maa,mii;
bool fla1,fla2;
long long sum=0,bb,cc;
while(scanf("%d",&n)&&n)
{
maxx=sum=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
if(a[i]>maxx)
maxx=a[i];
}
for(int i=0;i<=maxx;i++)
store[i].clear();
for(int i=1;i<=n;i++)
store[a[i]].push_back(i);
for(int i=1;i<=n;i++)
{
fla1=false;
fla2=false;
if(a[i]<=300)
{
for(int j=i-1;j>=1;j--)
{
if(a[j]%a[i]==0)
{
p=j;
fla1=true;
break;
}
}
if(fla1)
{
b=a[p];
}
else b=a[i];
for(int j=i+1;j<=n;j++)
{
if(a[j]%a[i]==0)
{
p=j;
fla2=true;
break;
}
}
if(fla2)
{
c=a[p];
}
else c=a[i];
//cout<<"c"<<i<<": "<<c<<" b"<<i<<": "<<b<<endl;
bb=b;
cc=c;
sum+=bb*cc;
}
else
{
maa=100005;
mii=-1;
tmp=a[i];
while(tmp<=maxx)
{
int si=store[tmp].size();
for(int k=0;k<si;k++)
{
if(store[tmp][k]>i)
{
if(store[tmp][k]<maa)
maa=store[tmp][k];
}
else if(store[tmp][k]<i)
{
if(store[tmp][k]>mii)
mii=store[tmp][k];
}
}
tmp+=a[i];
}
if(mii!=-1)
{
b=a[mii];
}
else b=a[i];
if(maa!=100005)
{
c=a[maa];
}
else c=a[i];
//cout<<"c"<<i<<": "<<c<<" b"<<i<<": "<<b<<endl;
bb=b;
cc=c;
sum+=bb*cc;
}
}
cout<<sum<<endl;
}
return 0;
}原文:http://blog.csdn.net/david_jett/article/details/46433051