最小异或问题,超出时间限制并在少数情况下给出不同的答案

问题描述

我正在尝试解决来自黑客等级的 Minimum AND xor OR 问题 (here),它在示例案例中运行良好,但在第一个输入案例场景中,数字测试用例 (T) 为 1000,它提供 20 个错误答案
例如:由 10 个数字组成的输入数组 [853,864,10,547,954,235,822,429,628,569] 给出结果 53,而正确的 ans 是 26。(其余980 是正确的),并且在输入案例场景的其余部分超出了时间限制。 我试图调试,但遇到了死胡同。
除了使用不同的排序方法(如qsort)之外,还有什么方法可以使它更可行?

#include <stdio.h>
int arr[100000];
int cal[1000000];

int arrinp(int arr[],int N)
{
    for (int i = 0; i < N; i++)
    {
        scanf("%d",&arr[i]);
    }
}

void sort(int arr[],int N)
{
    int temp;
    for (int i = 0; i < N - 1; i++)
    {
        for (int j = i + 1; j < N - 1; j++)
        {
            if (arr[i] > arr[j])
            {
                temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
            }
        }
    }
}

int arrcal(int arr[],int cal[],int N)
{
    sort(arr,N);
    int ans1;
    for (int i = 0; i < N - 1; i++)
    {
        cal[i] = arr[i] ^ arr[i + 1];
    }
    sort(cal,N);
}

int main()
{
    int T,N,temp;
    scanf("%d ",&T);
    for (int i = 0; i < T; i++)
    {
        scanf("%d ",&N);
        arrinp(arr,N);
        sort(arr,N);
        arrcal(arr,cal,N);
        sort(cal,N);
        printf("%d\n",cal[0]);
    }
}

解决方

#include <stdio.h>
int arr[100000];
int cal[1000000];

int arrinp(int arr[],&arr[i]);
    }
}

int compareInt(const void *pa,const void *pb)
{
    const int *p1 = pa;
    const int *p2 = pb;
    return *p1 - *p2;
}


int arrcal(int arr[],int N)
{
    int ans1;
    for (int i = 0; i < N - 1; i++)
    {
        cal[i] = arr[i] ^ arr[i + 1];
    }
}

int main()
{
    int T,N);
        qsort(arr,sizeof(int),compareInt);
        arrcal(arr,N);
        qsort(cal,N - 1,compareInt);
        printf("%d\n",cal[0]);
    }
}

感谢大家的帮助,qsort 解决了这两个问题。
P.S.:任何人都可以解释为什么 qsort 在上面的例子中给出了正确的答案(10 个元素)而函数 sort() 失败了?

解决方法

错误的结果和超出时间限制的两个问题似乎都是由这个例程引起的:

void sort(int arr[],int N)
{
    int temp;
    for (int i = 0; i < N - 1; i++)
    {
        for (int j = i + 1; j < N - 1; j++)
        {
            if (arr[i] > arr[j])
            {
                temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
            }
        }
    }
}

j 上的边界 j < N - 1 不正确,因为这意味着永远不会检查数组的最后一个元素。应该是 j < N

即使固定了,这也是 O(N2) 排序。这需要太长时间。好的 sorting algorithms 是 O(N log N)。标准 C 库中的 qsort 例程提供了一种高效的算法:

#include <stdlib.h>

static int CompareInt(const void *pa,const void *pb)
{
    // Convert "void *" pointers to "int *" and use them to get the int values.
    int a = * (const int *) pa,b = * (const int *) pb;
    if      (a < b)  return -1;
    else if (a == b) return  0;
    else             return +1;
}

void sort(int arr[],int N)
{
    qsort(arr,N,sizeof *arr,CompareInt);
}

此外,排序 cal 是不必要的。无需排序即可扫描数组的最小值。