对抛物线y = ax ^ 2 + bx + c x = x1,x2,x3,x4的坐标(x,y)进行排序。根据y坐标

时间:2016-04-14 09:00:07

标签: c++ arrays algorithm sorting computational-geometry

我尝试了一个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代码实现对我也有用。

1 个答案:

答案 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

现在,请更接近顶点的索引lr,并将其添加到列表中。更新索引,直到用尽列表为止。

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