我设法解决了SPOJ问题。它的时间限制为1秒。但我的算法运行时间不到400毫秒,但打印矩阵大约需要2秒。是否可以在不到700毫秒的时间内打印出来?
char matrix[30000][30];
我尝试用两个for循环打印它,然后用printf作为字符串逐行,然后我尝试了put也不是快速的。 我还尝试用put打印一组900000个字符。这是目前最快的方式(1.6s)。
下面的代码是我用数组写的最快的代码(30000 * 30 = 900000)。
#include <iostream>
#include <ctime>
#include<stdio.h>
using namespace std;
int main()
{
char array[900000];
for(int i = 0; i < 900000; i++)
array[i] = '.';
clock_t time_a = clock();
puts(array);
clock_t time_b = clock();
cout << endl;
cout << "Execution time of puts: " << (unsigned int)(time_b - time_a) << endl;
return 0;
}
答案 0 :(得分:2)
重新发布,评论中已经指出的内容:
array
应该为空终止 - 在for循环初始化后需要array[900000-1] = '\0';
或者可能发生错误,因为std::put
不知道何时停止。< / LI>
在我的机器上打印输出到控制台(./program
)需要2秒钟,但如果输出通过管道输送到文件(./program > out.txt
),则只需0.001秒。
答案 1 :(得分:1)
SPOJ正在寻找控制台上的输出(std::cout
)。不幸的是,这使得测试变得非常难看,因为输出需要几秒钟才能打印,使程序运行时偏向图形卡的限制而不是程序本身,并且通用控制台无法保持整个输出,因此很难将输出验证为正确
解决方案一:使用std :: cout将输出打印到控制台,但让操作系统将控制台输出重定向(AKA管道)到文件。这是通过两个窗口上的以下运算符和我玩过的大多数* nix变体来完成的。
program.exe > outputfile.txt
>
运算符表示重定向。
简单的黑客测试代码证明如下:
#include <iostream> //cout
#include <chrono> // clock
#include <cstring> //memset
char courtMatrix[90000];
void printFile(char * matrix,
size_t len)
{
for (size_t i = 0; i < len - 1; i++)
{
std::cout << matrix[i] << "\n";
}
std::cout << matrix[len - 1];
}
int main()
{
// not using c-style standard IO, no sense paying for it.
std::cout.sync_with_stdio(false);
//initialize array contents
memset(courtMatrix, '.', sizeof(courtMatrix));
//start timer
auto start = std::chrono::high_resolution_clock::now();
//TODO generate output here
//print output
printFile(courtMatrix, sizeof(courtMatrix));
// compute duration
auto dur = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now() - start);
//output execution time. Note cerr, not cout. Different data stream and
//won't pipe to file
std::cerr << "Execution time : " << dur.count() << std::endl;
return 0;
}
执行
test > test.txt
典型输出:一个test.txt文件和
执行时间:0
关于size_t
的快速说明。 size_t
是一个无符号整数,足以索引系统上可表示的最大对象。这意味着它足以处理您可以构建的任何阵列。它还消除了测试负数和垃圾的需要,因为负数将包裹到一个巨大的正数,并将被上限检查捕获。方便用于索引。
回到主题,上面的printFile
函数的输出将被SPOJ拒绝,因为输出要求似乎想要2D矩阵并且偏离这个可能会导致失败。在那种情况下:
void printFile(char * matrix,
size_t len,
size_t rowlength)
{
size_t rowleft = rowlength;
for (size_t i = 0; i < len; i++)
{
std::cout << matrix[i] << ' ';
rowleft--;
// test if we've printed an entire row
if (rowleft == 0)
{
// we have, so end the line and reset the counter
rowleft = rowlength;
std::cout << '\n';
}
/* could use the more elegant-looking
if (i % rowlength) std::cout << '\n';
but the % operator is often pretty expensive compared to --
As always, test it and find out which suits your needs better.
*/
}
}
不要害怕使用2D数组并在此处嵌套for循环。一旦使用优化编译器,改进的可读性可能会超过任何性能损失。如果我错了,可以通过一些分析会很快告诉你。
答案 2 :(得分:0)
无法将输出重定向到文件,并以某种方式让SPOJ在输出文件中检查您的答案。
但是,可以对您进行一些优化。例如,cout
不是向标准输出写入内容的最快方式。
看一下这篇文章:Yet again on C++ input/output
作者讨论并比较了C ++中用于竞争性编程的几种I / O方法。