📜  快速I / O进行竞争性编程

📅  最后修改于: 2021-06-25 20:22:02             🧑  作者: Mango

在竞争性编程中,尽快读取输入很重要,这样可以节省宝贵的时间。

您肯定已经看到各种问题陈述:“警告:大型I / O数据,请谨慎使用某些语言(尽管如果算法设计良好,大多数应该可以)” 。解决此类问题的关键是使用更快的I / O技术。

通常建议使用scanf / printf而不是cin / cout来进行快速输入和输出。但是,您仍然可以使用cin / cout并通过在main()函数包含以下两行来达到与scanf / printf相同的速度:

ios_base::sync_with_stdio(false);

如果在程序执行其第一个输入或输出操作之前调用它,则将打开或关闭所有C++标准流与其对应的标准C流的同步。添加ios_base :: sync_with_stdio(false); (默认情况下为true)(在任何I / O操作中避免此同步之前)。它是std :: ios_base函数的静态成员。

cin.tie(NULL);

tie()是一种仅在std :: cin接受输入之前保证刷新std :: cout的方法。这对于交互式控制台程序很有用,因为交互式控制台程序需要不断更新控制台,但同时也会降低大型I / O程序的运行速度。 NULL部分仅返回一个NULL指针。

此外,您可以将标准模板库(STL)包含在单个include中:

#include 

因此,用于竞争性编程的模板可能如下所示:

#include 
using namespace std;

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    return 0;
}

建议使用cout <<“ \ n”;而不是cout << endl;。 endl较慢,因为它会强制执行冲洗流,这通常是不必要的(有关详细信息,请参见此内容)。 (例如,如果您正在编写交互式进度条,则需要刷新,但在写入一百万行数据时则不需要刷新。)写’\ n而不是endl。

我们可以在问题INTEST – SPOJ上的巨大输入测试中测试我们的输入和输出方法。在继续阅读之前,建议您先解决该问题。

C++ 4.9.2中的解决方案

普通I / O:下面的代码使用cin和cout。该解决方案以2.17秒的运行时间被接受。

// A normal IO example code
#include 
using namespace std;
int main()
{
    int n, k, t;
    int cnt = 0;
    cin >> n >> k;
    for (int i=0; i> t;
        if (t % k == 0)
            cnt++;
    }
    cout << cnt << "\n";
    return 0;
}

快速的I / O但是,通过添加两行代码,我们可以做得更好,并且可以大大减少运行时间。下面的程序以0.41秒的运行时间被接受。

// A fast IO program
#include 
using namespace std;
  
int main()
{
    // added the two lines below
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);   
      
    int n, k, t;
    int cnt = 0;
    cin >> n >> k;
    for (int i=0; i> t;
        if (t % k == 0)
            cnt++;
    }
    cout << cnt << "\n";
    return 0;
}

现在,谈论诸如ACM ICPC,Google CodeJam,TopCoder Open之类的竞争竞赛,这是一种以最快的方式读取整数的专有代码。

void fastscan(int &number)
{
    //variable to indicate sign of input number
    bool negative = false;
    register int c;
  
    number = 0;
  
    // extract current character from buffer
    c = getchar();
    if (c=='-')
    {
        // number is negative
        negative = true;
  
        // extract the next character from the buffer
        c = getchar();
    }
  
    // Keep on extracting characters if they are integers
    // i.e ASCII Value lies from '0'(48) to '9' (57)
    for (; (c>47 && c<58); c=getchar())
        number = number *10 + c - 48;
  
    // if scanned input has a negative sign, negate the
    // value of the input number
    if (negative)
        number *= -1;
}
  
// Function Call
int main()
{
    int number;
    fastscan(number);
    cout << number << "\n";
    return 0;
}

如果您希望与行业专家一起参加现场课程,请参阅《 Geeks现场课程》和《 Geeks现场课程美国》。