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

时间:2014-08-02 07:04:17

标签: c++ time-limiting

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

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

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

我的解决方案:

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

Checker的日志:

  

测试:#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 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 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 个答案:

答案 0 :(得分:0)

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

从您的代码中,通过const ref而不是值传递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