C中的运行时错误(CodeChef)

时间:2014-08-17 10:31:56

标签: c runtime-error

我正在CodeChef解决问题。问题链接是:: http://www.codechef.com/problems/POINTS

在这个问题中,我们将2D平面中的坐标作为用户的输入,然后从具有最小x坐标和最大y坐标的点移动到最大x坐标和最小y坐标,然后计算行进距离。

我打算做的是,从用户那里输入所有点,然后使用x和y坐标给出的条件对它们进行排序。

这是我的代码::

#include<stdio.h>


int x[100000][2];//coordinates
int c[100000][2];

void sort(int a[][2], int low, int high);           //sorting the points
void merge(int a[][2],int low, int mid,int high);   //merge sort
int main()
{
    int t;//number of test cases
    int n;//number of points

    int i;
    scanf("%d",&t);
    while(t--)
    {
        printf("\n");
        scanf("%d",&n);


        for(i=0;i<n;i++)
            scanf("%d %d",&x[i][0],&x[i][1]);

        sort(x,0,n-1);

        for(i=0;i<n;i++)
            printf("%d %d\n", x[i][0],x[i][1]);

    }
    return 0;
}

void sort(int a[][2], int low, int high)
{
    int mid;
    while(low<high)
    {
        mid=(low+high)/2;
        sort(a,low,mid);
        sort(a,mid+1,high);
        merge(a,low,mid,high);
    }
}

void merge(int a[][2],int low, int mid,int high)
{
    int i=low, j=mid+1;
    int k=low;
    while(i<=mid && j<=high)
    {
        if(a[i][0]<a[j][0])
        {
            c[k][0]=a[i][0];
            c[k][1]=a[i][1];
            i++;k++;
        }
        else if(a[i][0]>a[j][0])
        {
            c[k][0]=a[j][0];
            c[k][1]=a[j][1];
            j++;k++;
        }
        else
        {
            if(a[i][1]>a[j][1])
            {
                c[k][0]=a[i][0];
                c[k][1]=a[i][1];
                i++;k++;
            }
            else
            {
                c[k][0]=a[j][0];
                c[k][1]=a[j][1];
                j++;k++;
            }
        }
    }
    for(i=low;i<=high;i++)
    {
        a[i][0]=c[i][0];
        a[i][1]=c[i][1];
    }
}

我认为数组大小太大而导致运行时错误,所以我尝试将数组大小减小到100然后运行程序,但它仍然会导致运行时错误。 现在,在我发布的代码中,我只希望对坐标进行排序。 排序条件是::(在问题中给出)

从具有最小X和最大Y值的点开始,并以具有最大X和最小Y值的点结束。移动规则是,与您所在点的X值相比,您无法移动到X值较小的点。此外,对于具有相同X值的点,您需要在访问具有相同X值的下一个点之前访问具有最大Y值的点。因此,如果有2个点:(0,4和4,0)我们将从(0,4)开始 - 即最少X优先于最大Y.你需要访问飞机中的每个点。

1 个答案:

答案 0 :(得分:1)

好的,我想我已经发现了问题:

  1. sort()中,将while替换为if。没有理由在那里进行循环 - 你通过递归来做到这一点
  2. merge()中的循环条件不正确。如果ij超出范围,则其他合并切片的其余部分不会合并到c中。我建议迭代k,因为无论如何你需要迭代整个目标范围。请注意,在迭代k时,您需要检查ij是否超出范围 - 如果是,则只需复制另一个切片中的元素。我使用短路评估来做到这一点,也就是说,边界检查语句在<{em> ||运算符之前,这很重要,否则无法访问无效的内存! (如果需要,请随时询问进一步的解释)
  3. 这是应用上述修复后的代码:

    void sort(int a[][2], int low, int high)
    {
        int mid;
    
        if(low < high)
        {
            mid=(low+high)/2;
            sort(a,low,mid);
            sort(a,mid+1,high);
            merge(a,low,mid,high);
        }
    }
    
    void merge(int a[][2],int low, int mid, int high)
    {
        int i = low,
                j = mid + 1,
                k = low;
    
        for (k = low; k <= high; k++)
        {
            if((j > high) || (a[i][0] < a[j][0]))
            {
                c[k][0]=a[i][0];
                c[k][1]=a[i][1];
                i++;
            }
            else if((i > mid) || (a[i][0] > a[j][0]))
            {
                c[k][0]=a[j][0];
                c[k][1]=a[j][1];
                j++;
            }
            else  // Neither i nor j are out of bounds and the 0 element is equal
            {
                if(a[i][1] > a[j][1])
                {
                    c[k][0] = a[i][0];
                    c[k][1] = a[i][1];
                    i++;
                }
                else
                {
                    c[k][0] = a[j][0];
                    c[k][1] = a[j][1];
                    j++;
                }
            }
        }
        for(i = low; i <= high; i++)
        {
            a[i][0] = c[i][0];
            a[i][1] = c[i][1];
        }
    }
    

    我相信上面的代码可以满足您的需求。

    一些一般性建议:您可能希望使用简单的结构来存储坐标。代码将变得更容易阅读 - 更容易阅读的代码也更容易调试。此外,如果可能,通常应避免使用全局变量。