我尝试了一个cpp代码块:
bool comp(const pair<int,int>&A, const pair<int,int>&B)
{
if(A.second<=B.second)
{
if(A.first>=B.first)
return 1;
else
return 0;
}
return 0;
}
int main()
{
int a, b, c, x[10], y[10];
cin>>a;
cin>>b;
cin>>c;
for(int i=0;i<4;++i)
{
cin>>x[i];
y[i]=a*x[i]*x[i]+b*x[i]+c;
}
vector<pair<int,int> >V;
for(int i=0;i<4;++i)
{
V.pb(mp(x[i],y[i]));
}
for(int i=0;i<4;++i)
{
sort(V.begin(),V.end(),&comp);
}
for(int i=0;i<V.size();i++)
{
cout<<V[i].first;
cout<<" "<<V[i].second<<" ";
}
return 0;
}
STDIN:a b c x1 x2 x3...
和x
按顺序排列,即x1 < x2 < x3
。代码应使用每个y = y1 y2 y3
的抛物线方程生成一个新列表(x
),并对运行时复杂度为&lt; = O(log n)的上述列表进行排序。
STDOUT:x3,y3 x1,y1 x2,y2 ...
(假设计算y3 < y1 < y2..
)
代码不应该计算Y.此计算节点上的乘法“太”代价太高。解决方案应该确定一种仍然对列表进行排序而不计算“y”值的方法
我的代码计算y值。任何人都可以在不计算y值的情况下找到排序方法。 python代码实现对我也有用。
答案 0 :(得分:0)
x
值离抛物线的顶点x0
越远,y
为正a
值越高,y
值越低a
|x1 - x0| > |x2 - x0| && a > 0 --> y1 > y2
|x1 - x0| > |x2 - x0| && a < 0 --> y1 < y2
为负值时的{1}}值。
a
当x
为零时,您的抛物线实际上是一条线,当b
为正时,b
值已按正确顺序排序,或a
时以相反顺序排序是否定的。
所以当 x0 = - b / (2*a)
不为零时,找到顶点:
x
现在找到最接近x
的{{1}}值的排序列表中的值:
i = index(x: min(|x - x0|))
将点i
添加到列表中。创建两个索引:
l = i - 1
r = i + 1
现在,请更接近顶点的索引l
或r
,并将其添加到列表中。更新索引,直到用尽列表为止。
当a
为否定时还原列表。 (或者从列表末尾添加项目。)
编辑:这是Python中的一个实现。它从子列表中弹出元素而不是使用数组索引,但逻辑是相同的:
import bisect
def parasort(a, b, c, x):
"""Return list sorted by y = a*x*x + b*x + c for sorted input x."""
if not x:
return x
if a == 0: # degenerate case: line
if b < 0: return x[::-1]
return x[:]
x0 = -0.5 * b / a # apex of parabola
i = bisect.bisect_left(x, x0) + 1 # closest point via bin. search
l = x[:i][::-1] # left array, reverted
r = x[i:] # right array
res = []
while l and r: # merge l and r
if x0 - l[0] > r[0] - x0: # right item is smaller
res += [r.pop(0)]
else: # left item is smaller
res += [l.pop(0)]
res += l + r # append rest of arrays
if a < 0: return res[::-1]
return res
a = 4
b = 0
c = 0
xx = parasort(a, b, c, [-3, 0, 1, 2])
for x in xx:
print x, a*x*x + b*x + c