生成排列的时间优化(竞争编程)

Time optimization for generating permutations (competetive programming)

本文关键字:竞争 编程 优化 时间 排列      更新时间:2023-10-16

我正在努力优化竞争性编程问题的速度。到目前为止,我已经完成了这个代码。问题是关于按字典顺序得到N上的所有排列。如果有可能让它跑得更快,你能提出一些想法吗?

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int n;
    scanf("%d", &n);
    int v[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    do
    {
        for(int i = 0; i < n; i++)
            printf("%d ", v[i]);
        printf("n");
    } while(next_permutation(v, v+n));
    return 0;
}

以下是一些可以尝试的技术,并非所有技术都能显著节省:

将编译器优化设置为高速

首先,让编译器尝试优化代码。打印出汇编语言列表,看看编译器做了什么。将这些优化合并到C++代码中(如果可能的话)。

使用块(批量)输出

对于许多应用程序来说,输出是花费大部分时间的地方。

尝试对字符缓冲区使用snprintf,然后在程序结束时,使用块写入(fwrite)将字符缓冲区写入输出流。

对于大多数输出流,一个大事务比许多小事务更有效率。

循环展开

在循环体中重复语句以减少迭代次数。

大多数处理器不喜欢分支指令,因为它们要么调用代价高昂的分支预测算法,要么导致指令管道清空。例如,消除分支意味着在分支预测中不浪费时间。

在您的情况下,这可能并不重要,因为您在循环中进行函数调用。

专业化格式化输出

printf函数针对通用输出进行了优化:转换格式规范和输出数据。

您可以通过编写自己的转换函数来节省一些时间,该函数消除了格式规范的翻译。例如,您的函数只输出十进制,因此您可以编写自己的函数,将整数转换为文本缓冲区,然后输出文本缓冲区(请参见fwriteputs)。

编写自己的排列函数

同样,std::next_permutation是为泛型而设计的。您可能可以编写自己的更专业化或优化的应用程序。