【问题标题】:Minimum XOR problem, exceeds the time limit and gives different answers in few cases最小异或问题,超过时间限制,在少数情况下给出不同的答案
【发布时间】:2021-07-18 23:03:54
【问题描述】:

我正在尝试解决黑客级别的最小 AND xor OR 问题 (here),它在示例案例中运行良好,但在第一个输入案例场景中,测试次数case(T) 为 1000,它提供 20 个错误答案
例如:10 个数字的输入数组 [853, 864, 10, 547, 954, 235, 822, 429, 628, 569] 给出的结果是 53,而正确的答案是 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[], int N)
{
    for (int i = 0; i < N; i++)
    {
        scanf("%d", &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 cal[], int N)
{
    int ans1;
    for (int i = 0; i < N - 1; i++)
    {
        cal[i] = arr[i] ^ arr[i + 1];
    }
}

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

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

【问题讨论】:

  • @πάνταῥεῖ 我这样做是为了建立我的逻辑。而且我认为许多有竞争力的程序员最终会进入 FAANG 公司。如果我错了,请纠正我。
  • @molbdnilo 这一点都不明显,但似乎是正确的。 &amp;^| 折叠成普通的异或,如果您对数字进行排序,最小对确实可能彼此相邻。这需要一些推理(不确定OP是否真的这样做了......)。我认为真正的问题是排序忽略了最后一个元素,它首先是冒泡排序......
  • 您可以忽略 πάντα ῥεῖ 的 cmets。它们是没有根据的观点,在表述和实质上都有些不恰当。也就是说,这类练习通常看起来不是教程,因为它们不是教学概念。解决它们可能需要使用各种概念,因此它们可能是练习您在其他地方学到的东西或展示您在其他地方学到的东西的机会。但实际上首先学习这些概念通常需要从教科书或其他资源中学习。
  • 如果竞争性编程练习本身的价值有限,因为它不是教程,那么在 Stack Overflow 上询问它是一个提供缺失值的机会,通过提供对有价值概念的解释和讨论。所以结束这个问题是一个糟糕的决定。
  • @Damien:我认为你在写作;他们的arrcal 似乎包含了我讨论的想法,所以我删除了那些 cmets。所以超出时间限制的实际原因是排序。

标签: c++ arrays c data-structures time-complexity


【解决方案1】:

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

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;
            }
        }
    }
}

jj &lt; N - 1 上的边界不正确,因为这意味着永远不会检查数组的最后一个元素。应该是j &lt; 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 进行排序。无需排序即可扫描数组的最小值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-12
    • 1970-01-01
    • 2013-07-05
    • 1970-01-01
    • 2014-10-30
    相关资源
    最近更新 更多