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?
№ | Пользователь | Рейтинг |
---|---|---|
1 | tourist | 4009 |
2 | jiangly | 3823 |
3 | Benq | 3738 |
4 | Radewoosh | 3633 |
5 | jqdai0815 | 3620 |
6 | orzdevinwang | 3529 |
7 | ecnerwala | 3446 |
8 | Um_nik | 3396 |
9 | ksun48 | 3390 |
10 | gamegame | 3386 |
Страны | Города | Организации | Всё → |
№ | Пользователь | Вклад |
---|---|---|
1 | cry | 167 |
2 | Um_nik | 163 |
3 | maomao90 | 162 |
3 | atcoder_official | 162 |
5 | adamant | 159 |
6 | -is-this-fft- | 158 |
7 | awoo | 157 |
8 | TheScrasse | 154 |
9 | Dominater069 | 153 |
9 | nor | 153 |
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?
Название |
---|
Just include
std::ios::sync_with_stdio(false);
in your code, and cin will be as fast as scanf.In which part of the code?
Try putting it at the very first line inside method main()
ok, thank you!!
Then mukel why isn't it there by default? Any disadvantages of the same?
You can't use both cin/cout and printf/scanf.
Technically, one can still use both cin/cout and scanf/printf together, but will have to manually handle flushing the buffer(s), which is tedious.
But I have seen different cases.
Check this two submissions of me: 11250063 and 11224282.
First one was TLE though I used what you recommended.
The problem is the output, cout << endl flushes the output every time wich hit performance badly. To output an end line without flushing just use #define endl '\n'
Yeah I got that. Actually I have tried that also. It works.
Now my question is, if I do everything as recommended about cin/cout, will it be enough to solve all problems?
I find that confusing.
Just a few minutes ago, I have solved this problem at spoj: http://www.spoj.com/ranks/INVCNT/start=20
This is a simple problem of counting inversions. I just implemented BIT.
By the way, the thing is, I made three submissions for the problem. Check out this screenshot:
So you can see the difference. The first one was using scanf/printf. Second one was with cin/cout+sync_with_stdio and the third one used just cin/cout.
Looks like the screenshot is not loading. Here is the link:
http://pasteboard.co/NHHPeQX.png
It depends on the compiler. In codeforces cstdio is faster. I wonder how many blogs are there about this :P
It happened in Round #304 Div2 Problem D.
I submitted the problem with cin, cout and used
std::ios::sync_with_stdio(false);
The submission with cin, cout got TLE on 3rd testcase:
Link: http://mirror.codeforces.com/contest/546/submission/11225677
whereas the same solution passed with scanf and printf.
Link: http://mirror.codeforces.com/contest/546/submission/11342025
Can you explain why this happened?
just replace endl with "\n"
Using
std::ios::sync_with_stdio(false);
on SPOJ gave Runtime error for this problem. By removingstd::ios::sync_with_stdio(false);
it got accepted. Why?You should not mix cin/cout and scanf/printf once you have that "magic" line :)
Got it. Thanks!
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.
Does this apply to all streams? i.e. reading files with
ifstream
orofstream
ios_base::sync_with_stdio()
only affects standard streams; there's probably nothing you can do to speed upifstream
/ofstream
, except for not usingendl
or changing their buffer sizes.But fstream is even faster than iostream with ios_base::sync_with_stdio()
This is placebo. The function only affects standard streams. In case of
fstream
there is not even a corresponding C stream to synchronize with.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.You might find this post of mine useful: http://mirror.codeforces.com/blog/entry/5217
Untie of stream may also help http://www.cplusplus.com/reference/ios/ios/tie/
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")Put
#define endl '\n'
, and you don't need to worry about it anymore :)Check this I have used
endl
withios_base::sync_with_stdio(false);cin.tie(0);
and it worked.try it in a problem which requires you to answer 10^5 or more queries. this question doesnt require fast I/O. try this problem http://mirror.codeforces.com/contest/456/problem/E just copy any accepted C++ solution and submit it with endl and ios_base::sync_with_stdio(false);cin.tie(0); it will fail. check my submission history.
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)
fastest I is getchar_unlocked()
just found out this blog is 2 years old ;|
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:
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 =)!
getchar_unlocked gave CE on CF. Would you please check?
11338997
i don't know since i haven't worked with getchar_unlocked() but i know it is the best form of getting input
http://stackoverflow.com/questions/13010505/getchar-unlocked-in-windows-undeclared most problems can be solved by googling a little
You are right =). I didn't even know CF used Windows system! O.o I remember having used getchar_unlocked on CF in the past, but I'm probably wrong then.
I use Windows on my machine because I play a lot, and it's incovenient to keep rebooting. So, what I did was to add the following line to my stdio.h:
#define getchar_unlocked getchar
About it not working on CF, though, there is nothing we can do =/.
P.S.: using getchar is still faster than scanf, of course. But it usually isn't fast enough to make the difference (make a TLE become an AC).
I use this recently, and work very good :
Please format it.
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 sometimesprintf
,scanf
etc. in the same code ? I mean, can I switch ON / OFFstd::ios::sync_with_stdio();
whenever I want ?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.
I don't like tradeoffs, so I ended up writing my own version http://mirror.codeforces.com/blog/entry/45835
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)
I also had same experience for light oj problem no. 1088. Please explain if anybody knows why?? is it platform issue or something else??
LightOJ has some weird issues with fast IO. Use
scanf
/printf
in LightOJ and you should be fine.