题意就是对于给定不同取值的a,b,c,d,n,求f(x)的最小值
时间紧凑,字体丑陋:
/*
求二次函数最小值,
当A<=0时:
min(f(L),f(R));
当A>0时:
此时应该用三分求出最值
*/
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std;
typedef long long ll;
ll inf=1e18+10;
vector<int> v[100];//每一个x对应的g(x)的值
int work(int x){
int t=0;
while(x){
t+=x%10;
x/=10;
}
return t;
}
void init(){
for(int i=1;i<=1000010;++i)
{
v[work(i)].push_back(i);
}
}
void solve(){
int a,b,c,d,n;
scanf("%d%d%d%d%d",&a,&b,&c,&d,&n);
ll ans=inf;
for(int i=1;i<=54;++i)
{
if(v[i].size()==0)continue;
int l=0;
int r=upper_bound(v[i].begin(),v[i].end(),n)-v[i].begin();
if(r==0)continue;
r--;
ll A=(ll)a*i+b;
ll B=(ll)c*i*i+d*i;
if(A<=0)//该函数的最小值只会存在于两端点处
{
ans=min(ans,(ll)A*v[i][l]*v[i][l]+B*v[i][l]);
ans=min(ans,(ll)A*v[i][r]*v[i][r]+B*v[i][r]);
}
else//三分求解最小值
{
ll ansL=inf,ansR=inf;
while (l<=r)
{
int lmid = l+(r-l)/3;
int rmid = r-(r-l)/3;
ansL = (ll)v[i][lmid]*A*v[i][lmid]+B*v[i][lmid];
ansR = (ll)v[i][rmid]*A*v[i][rmid]+B*v[i][rmid];
if(ansL <= ansR)
r = rmid-1;
else
l = lmid+1;
}
ans=min({ans,ansL,ansR});
}
}
printf("%lld\n",ans);
}
int main(){
init();
int T;
scanf("%d",&T);
while(T--)
solve();
return 0;
}