Блог пользователя ed1d1a8d

Автор ed1d1a8d, 13 лет назад, По-английски

What form of I/O should we use in competitive programming?

For example scanf and printf are undoubtedly faster than cin and cout, but the later two are easier and faster to code. How should we adress this tradeoff?

  • Проголосовать: нравится
  • 0
  • Проголосовать: не нравится

»
13 лет назад, скрыть # |
 
Проголосовать: нравится +1 Проголосовать: не нравится

Just include std::ios::sync_with_stdio(false); in your code, and cin will be as fast as scanf.

»
13 лет назад, скрыть # |
 
Проголосовать: нравится +12 Проголосовать: не нравится

Like mukel said, ios_base::sync_with_stdio(0) makes c++ io streams' performance comparable to cstdio's. Have a look at the following thread: http://mirror.codeforces.com/blog/entry/925, as well as here: The Standard Librarian: IOStreams and Stdio.

Once, at another Online Judge, I kept getting TLE's for an algorithm that was quite IO intensive. I was using cin/cout and ios_base::sync_with_stdio(0) as the first line of main()'s body. I switched back to scanf/printf and got AC. Depends on the implementation. To me, it works wonderfully at CodeForces.

PD:Also, favor '\n' instead of endl for ending lines. endl flushes the buffer every time.

»
13 лет назад, скрыть # |
 
Проголосовать: нравится +5 Проголосовать: не нравится

but also notice: with std::ios::sync_with_stdio(false);, don't mix C-style IO (scanf/printf, gets/puts, getchar/putchar ... ) with C++-style IO (cin/cout ... ), since cin/cout is not sync with stdio, you may get same data from using scanf and then use cin again.

»
13 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

You might find this post of mine useful: http://mirror.codeforces.com/blog/entry/5217

»
13 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится
»
12 лет назад, скрыть # |
Rev. 2  
Проголосовать: нравится 0 Проголосовать: не нравится

Put this: ios_base::sync_with_stdio(false);cin.tie(0); in the beggining of the main func. cin/cout will be as fast as scanf and printf (even faster). BUT DONT USE ENDL (use "\n")

»
12 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

I use stringstream to store output first and output it on the last line as cout << ss.str();.

This works great when you input and output alternatively. (For example, when you output as you answer query)

»
11 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

fastest I is getchar_unlocked()

  • »
    »
    11 лет назад, скрыть # ^ |
     
    Проголосовать: нравится +19 Проголосовать: не нравится

    just found out this blog is 2 years old ;|

    • »
      »
      »
      11 лет назад, скрыть # ^ |
       
      Проголосовать: нравится +10 Проголосовать: не нравится

      Two years old, but no one else said anything about getchar_unlocked =P.

      It was really hard to convince myself to move from C to C++ half a decade ago, but I did. I never liked cin/cout though, so I still use scanf/printf instead, and that probably won't change.

      In the very rare times I need fast input reading (like when the input size is O(n) and an O(n) solution is expected, but mine is O(n lg n)): for (x = 0; (c = getchar_unlocked()) >= '0'; x = x*10+c-'0'); // reads int to x

      Usually I write it as the following function:

      inline void scan_uint(int* p) {
          static char c;
          while ((c = getchar_unlocked()) < '0'); // just to be safe
          for (*p = c-'0'; (c = getchar_unlocked()) >= '0'; *p = *p*10+c-'0');
      }
      

      Making it parse input as float, string, int with sign, return if eof, etc should be easy too... getchar_unlocked already gave me two or three balloons, so I'm grateful to it =)!

»
11 лет назад, скрыть # |
Rev. 3  
Проголосовать: нравится +14 Проголосовать: не нравится

I use this recently, and work very good :


using namespace std; typedef long long i64; const int MAX_STRING_LENGTH = 1; #define endl "\n" struct _io{ char buff[MAX_STRING_LENGTH]; _io & operator >>(int &x){ scanf("%d",&x); return *this; } _io & operator >>(i64 &x){ scanf("%I64d",&x); return *this; } _io & operator >>(float &x){ scanf("%f",&x); return *this; } _io & operator >>(double &x){ scanf("%lf",&x); return *this; } _io & operator >>(long double &x){ scanf("%llf",&x); return *this; } _io & operator >>(char &c){ scanf("%c",&c); return *this; } _io & operator >>( char *s ){ scanf("%s",s); return *this; } _io & operator >>( string &s ){ scanf("%s",buff); s = string(buff,strlen(buff)); return *this; } _io & operator <<(int x){ printf("%d",x); return *this; } _io & operator <<(i64 x){ printf("%I64d",x); return *this; } _io & operator <<(float x){ printf("%f",x); return *this; } _io & operator <<(double &x){ printf("%lf",x); return *this; } _io & operator <<(long double &x){ printf("%llf",x); return *this; } _io operator <<(char &c){ printf("%c",c); return *this; } _io & operator <<( string &s ){ printf("%s",s.c_str()); return *this; } _io & operator <<( char *s ){ printf("%s",s); return *this; } }io; int main(){ int a, b; io>>a>>b; io<<(a+b)<<endl; }
»
11 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

Hey guys, thanks for such an excellent discussion. I've read the entire page, but forgive me if I missed something, as I am going to ask a stupid question. * What if sometimes I want to use cin cout and sometimes printf, scanf etc. in the same code ? I mean, can I switch ON / OFF std::ios::sync_with_stdio(); whenever I want ?

  • »
    »
    11 лет назад, скрыть # ^ |
     
    Проголосовать: нравится +3 Проголосовать: не нравится

    You wouldn't want to switch off the sync and then use both cin/cout and scanf/printf as it "may result in unexpectedly interleaved characters".

    As it has been thoroughly explained above, cin/cout with syncing off and '\n' instead of endl should be faster than scanf / printf because the latter should undergo parsing all the time.

    You must call the function before any input / output is done, so no, you shouldn't be toggling it.

»
10 лет назад, скрыть # |
 
Проголосовать: нравится +5 Проголосовать: не нравится

I don't like tradeoffs, so I ended up writing my own version http://mirror.codeforces.com/blog/entry/45835

»
8 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

Before few minutes, I have solved Light oj problem no: 1087,problem title: "Diablo". In that problem, at first, I have used cin/count along with ios_base::sync_with_stdio(false);cin.tie(0);. I have also used #define endl "\n" and used no printf/scanf, which gave me Runtime Error. Later on, I have given up only this part cin.tie(0); and everything was similar like the before which gave me Time Limit Exceed. At last, I have used only printf/scanf which gave me Accepted.

Can any body explain it? (Thanks In Advance)