TIME_LIMIT_EXCEEDED at Codeforces 558E

TIME_LIMIT_EXCEEDED at Codeforces 558E

本文关键字:Codeforces 558E at EXCEEDED LIMIT TIME      更新时间:2023-10-16

我是编程领域的初学者,我已经开始在Codeforces上解决问题,这是我在Codeforces上的第一个问题,当我提交这个问题解决方案时,使用这个代码A Simple Task

#include <iostream>
#include <string>
using namespace std;
void swapchar(char &x, char &y)
{
char temp;
temp = x;
x = y;
y = temp;
}
void main()
{
string s;
long n, q;
long i, j;
bool k;
cin >> n >> q;
cin >> s;
for (int x = 0; x<q; x++)
{
    cin >> i >> j >> k;
    if (i<1 || j<1 || i>n || j>n)
        break;
    if (k == 1)
    {
        for (int u = i - 1; u < j; u++)
        {
            for (int v = u + 1; v < j; v++)
            {
                if (s[u] > s[v])
                    swapchar(s[u], s[v]);
            }
        }
    }
    else if (k == 0)
        for (int u = i - 1; u < j; u++)
        {
            for (int v = u + 1; v < j; v++)
            {
                if (s[u] < s[v])
                    swapchar(s[u], s[v]);
            }
        }
}
cout << s << endl;
}

则codeforces的输出为:-

Time limit exceeded on test 6

和当我搜索它是什么测试6我发现:-

Test: #6, time: 5000 ms., memory: 12 KB, exit code: -1, checker exit code: 0, verdict: TIME_LIMIT_EXCEEDED
输入

2256 44182
kanqevxwgecliptqmdsgnflqyohgtukphlbmjxndbtjqujuafxankfghlseytdwdviamqjscacuyrghriuaihxtyersgnyvigenpflwequgbdusnvlgplxjxkqhjbdvkmufpoirqueufblnnrnbhmcnvewzfdonwjgswuneimtykntwgrlfqlvkdblwjzplhffzqpopbjmvrjcxyzgxqhkjbrgdqnipsipexpoozphfrgzboiiiskawtbhegerhvknrzljclhnpokpazhspsmzeiujddlpfireoyjzriickcuwtbimxjbhunedcdgaabztczkzmahnriarzcmnkjrrfqkodxbpocmxjvutpqbmawcsghwxdidhmwbfxuqegpjtqfvaloycogvoxdtjotlknazaeofaxlomeywwlezlndhpjwbgpxgkvubropxffytucvlbhjugzqgglrezoqsrvwkdrbuehbjxtgobugghqrgbgacqi...
我不知道那个问题是什么意思,也不知道如何解决它

您正在使用复杂度为O(n^2)的选择排序(带有一些多余的交换),请尝试使用std::sort代替。您的代码中没有太多需要更改的地方:

#include <iostream>
#include <string>
#include <algorithm>
#include <functional>
using namespace std;
int main()
{
string s;
long n, q;
long i, j;
bool k;
cin >> n >> q;
cin >> s;
for (int x = 0; x<q; x++)
{
    cin >> i >> j >> k;
    if (i<1 || j<1 || i>n || j>n)
        break;
    if (k == 1)
    {
        std::sort(s.begin() + i-1,  s.begin() + j);
    }
    else if (k == 0)
        std::sort(s.begin() + i-1, s.begin() + j, std::greater<char>());
}
cout << s << endl;
}

std::sort(s.begin() + i-1, s.begin() + j);s.begin() + i-1排序到但不包括s.begin() + j。第二种方法只是通过使用> (std::greater)而不是<进行反向排序进行比较。注意std::sort对应#include <algorithm>, std::greater对应#include <functional>

请注意,我摆脱了你的swapchar函数,因为我们不再需要它了,我也改变了main的返回类型为int,因为它应该是。

上面的代码设法处理测试6,你有问题,但超过了测试9的时间限制(我甚至尝试了一些小的其他变化)。

要完成测试9+,您可能应该更多地考虑问题和可能的输入,以以下排序查询为例:

20 57   1
89 950  1
57 100  0
57 100  1
1  9500 0

这里我们会做大量无用的排序,如果第9个问题是为了测试你是否发现了这一点,我不会感到惊讶。首先对[20,57]和[89,950]范围按升序排序,然后对[57,100]范围按降序排序,并在完全覆盖第一个范围之后以升序调用相同的范围。最后,我们按降序对范围[1,9500]进行排序,覆盖之前我们可以完全忽略的所有排序,因为它们无论如何都被覆盖了。

我们可以利用后面的排序可以并且很可能将覆盖之前的排序。我们可以首先保存我们给出的所有"排序查询",然后从最后一个查询开始(因为那个查询无论如何都会覆盖所有之前的查询),并以相反的顺序只对我们尚未排序的范围进行排序。这样我们就可以摆脱很多无用的排序,即使我们稍后会覆盖它并大大加快它的速度。