【问题标题】:Time Limit Error On CodeChefCodeChef 上的时间限制错误
【发布时间】:2016-11-04 08:12:48
【问题描述】:

This Is The Question

这是我的解决方案:

#include <iostream>

using namespace std;

int main(){
    unsigned long numberOfGums;
    unsigned long hardnessLimit;
    unsigned long counter = 0;

    cin >> numberOfGums;
    cin >> hardnessLimit;

    unsigned long gums[numberOfGums];

    for(unsigned long i=0; i<numberOfGums; i++){
        cin >> gums[i];
    }

    for(unsigned long i=0; i<numberOfGums; i++){
        if(gums[i] < hardnessLimit){
            for(unsigned long j=i+1; j<numberOfGums; j++){
                if((gums[i] + gums[j]) < hardnessLimit){
                    counter++;
                }
            }
        }
    }

    cout << counter << endl;

    return 0;
}

这个程序给了我 TLE(Time Limit Exceeded) 错误,因此我在 100 分中只得到 30 分。具体来说,这个程序无法完成 子任务-2 值得剩下的 70 分(在问题页面上给出)。

我尝试过使用 printfscanf 代替 cincout 之类的东西,但程序仍然不够快。

我能做些什么来改进这个程序,或者有什么更好的方法来解决这个问题。

我也试过了,还是一样的错误:

#include <iostream>

using namespace std;

int main(){
    long numberOfGums;
    long hardnessLimit;
    long counter = 0;
    long temp = 0;

    cin >> numberOfGums;
    cin >> hardnessLimit;

    long gums[numberOfGums];

    for(long i=0; i<numberOfGums; i++){
        cin >> temp;
        if(temp < hardnessLimit){
            gums[i] = temp;
        }
    }

    for(long i=0; i<numberOfGums; i++){
        if(gums[i] != -1){
            for(long j=i+1; (j<numberOfGums); j++){
                if(((gums[i] + gums[j]) < hardnessLimit) && gums[j] != -1){
                    counter++;
                }
            }
        }
    }

    cout << counter << endl;

    return 0;
}

【问题讨论】:

  • 因为这可能是一个可以优化的蛮力解决方案。当 numberOfGums 可以大到 100,000 时,您有一个 o(n^2) 复杂度解决方案。
  • 你有什么更好的方法建议,对数组进行排序还是什么?
  • 请去掉 C 标签,这绝不是有效的 C 代码
  • 总是试着弄清楚你可以从输入数据的排序中获得什么。
  • @Virus 你为什么不认为对数组进行排序是行不通的?您发布的 O(n*n) 解决方案比排序和二进制搜索要慢得多。

标签: c++ algorithm


【解决方案1】:

您的解决方案是O(N^2),考虑到限制,它肯定会超时。

更有效的解决方案是O(NlogN) 解决方案。这是算法的基本大纲:

  • 对数组进行排序。这需要O(NlogN) 时间。

  • 1234563 .为此使用二进制搜索。找到此索引后,您可以轻松计算与元素p 关联的此类对的数量。这个完整的步骤需要 O(logN) 每个元素的时间
  • 对数组中除最后一个元素外的所有元素执行上述过程,因为其右侧没有数组。

你将通过总结你获得的每个元素p的所有对来得到答案

希望对你有帮助!!!

编辑:我正在添加上述算法的 C++ 实现。该解决方案通过了 CodeChef 上的所有测试用例。

#include <iostream>
#include <algorithm>
using namespace std;
int binsearch(int a[],int n, int x)
{
    int low, high, mid, k=-1;
    low = 0;
    high = n-1;
    while(low<=high)
    {
        mid = (low+high)/2;
        if(a[mid] <= x-1){
            k = mid;
            low = mid+1;
        }
        else{
            high = mid-1;
        }

    }
    return k;
}
int main() 
{
    int n, k, i, j;
    long long ans = 0;
    cin>>n>>k;
    int arr[n];

    for(i=0;i<n;i++)
    {
        cin>>arr[i];
    }

    sort(arr,arr+n);

    j = 0;

    while(j<n-1)
    {
        if(k-arr[j] > 0)
        {
            int ind = binsearch(arr,n,k-arr[j]);
            ans = ans + (ind-j>=0 ? (ind-j):0);
        }
        j++;
    }
    cout<<ans<<endl;
    return 0;

}

【讨论】:

  • 如果你使用int arr[n] 之类的东西,它就不是 C++。那不是有效的 C++。有时,堆栈溢出会导致错误。您应该将其更改为std::vector 此外,可以使用std::lower_bound 而不是编写自己的二进制搜索。
  • @PaulMcKenzie:我不是 C++ 专家。在解决竞争性编码问题时,即使在 C++ 中,我也更喜欢使用类似 C 的语法。查看作者的代码,很可能他对向量的了解不多。所以我试图从语法的角度使解决方案尽可能简单。
  • @MrSmith42 它仍然是有效的 c++ 代码 -- 不,它不是。可变长度数组从来都不是有效的 C++ 代码,并且说代码是正确的 C++ 是一种误导。此外,它与问题非常相关,因为存在使用此类数组是问题的原因(堆栈内存问题和 seg 错误)的问题,其中 std::vector 的使用解决了问题。可以看到here,代码使用Visual Studio 2015编译失败。
【解决方案2】:

TLE(Time Limit Exceeded) 当您的程序未在规定时间内完全运行时发生。 在竞争性编程中,出现 TLE 是因为程序花费的时间超过了输出的时间限制。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多