Codeforces 解决方案中超出时间限制。如何改进我的解决方案?

Posted

技术标签:

【中文标题】Codeforces 解决方案中超出时间限制。如何改进我的解决方案?【英文标题】:Time Limit Exceeded in Codeforces solution. How can I improve my solution? 【发布时间】:2014-08-02 07:04:16 【问题描述】:

问题-http://codeforces.com/contest/454/problem/B

问题概要- 给定的整数序列将通过应用移位操作更改为升序(每个元素向右移动 1 位,最后一个元素成为第一个)。找到使序列升序的最小操作数。如果不可能,则打印 -1。

我在上面的链接中获得了测试用例 6 的 TIME_LIMIT_EXCEEDED。我知道这个问题有更有效的解决方案,但如果可能的话,我想对我的解决方案进行更改,使其在时限内运行。那可能吗?如果是,我该怎么做?

我的解决方案:

#include<iostream>
#include<vector>
#include<cstring>
#include<cmath>
#include<algorithm>

typedef long long LL;

using namespace std;

bool checkAsc(vector<int> x, int N)

    for(int i=0;i<(N-1);i++)
    
        if(x[i+1]<x[i])
            return false;
    

    return true;


vector <int> shiftRight(vector <int> &x, int N)

    int temp=x[N-1];

    for(int i=(N-1);i>=1;i--)
    
        x[i]=x[i-1];
    

    x[0]=temp;

    vector <int> y=x;

    return y;


bool ifPossible(vector <int> x, int N)

    for(int i=1;i<(N-1);i++)
    
        if((x[i]>x[i-1])&&(x[i]>x[i+1])&&(x[i+1]>x[i-1]))
            return false;
    

    return true;


int main()

    int n, turns=0;
    vector <int> a(100000);

    cin>>n;
    for(int i=0;i<n;i++)
        cin>>a[i];

    if(!ifPossible(a, n))
        cout<<"-1";

    else
    
        while(!checkAsc(a, n))
        
            shiftRight(a, n);
            turns++;
        

        cout<<turns;
    

    return 0;

检查员的日志:

测试:#6,时间:1000 毫秒,内存:784 KB,退出代码:-1,检查器退出代码:0,判断:TIME_LIMIT_EXCEEDED 输入 99998

99997 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 462 44 47 48 49 50 51 52 53 53 54 50 60 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 92 92 93 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 15...

【问题讨论】:

问题的概要,而不仅仅是一个链接,将是一个好主意,原因与不鼓励仅链接的答案相同:链接会随着时间的推移而失效,如果该链接失效,那么未来用户的这个问题将随之消失。 【参考方案1】:

首先,修正你的算法,对于3, 2, 1,你有无限循环(而不是-1)。

在您的代码中,通过 const ref 而不是 value 传递 vector 以避免无用的副本。 你的shiftRight 可以使用vector.insert(v.back()); vector.pop_back(),这同样复杂,但是使用一些更快的方法(如memcpy);并将返回类型更改为void(因为未使用结果),因此丢弃y 及其副本。

但您的算法仍然是 O(N²) 而它可以在 O(N) 中完成

int get_unicorn_shift(const std::vector<int>& v)

    auto mid = std::is_sorted_until(v.begin(), v.end());
    if (mid == v.end()) 
        return 0;
    
    auto end = std::is_sorted_until(mid, v.end());
    if (end != v.end() || v.front() < v.back()) 
        return -1;
    
    return end - mid;

Live example

【讨论】:

以上是关于Codeforces 解决方案中超出时间限制。如何改进我的解决方案?的主要内容,如果未能解决你的问题,请参考以下文章

PostgresQL 中超出堆栈深度限制(删除触发器后)

无法执行 dex:Eclipse 中超出了 GC 开销限制

带有连接的 Sparkjob 中超出了 GC 开销限制

线程“main”中的异常java.lang.OutOfMemoryError:GWT应用程序中超出了GC开销限制

如何克服Excel中超链接的限制?

如何管理 SVG 文件中超出范围的值?