VJ 172735 F - Drying 从TLE到刚好AC再到妥妥AC 以及超级巨坑iostream

Donny

题目链接:

F - Drying CSU-ACM2017暑假集训2-二分搜索

二分。

wa得最多的一题。

一开始想投tou机lan用priority_queue结果TLE。

自己想了下就是"连求模都没有就想过追加的F题"。

乖乖改用二分,结果没考虑除0,RE了。

然后各种姿势wa ...

然后发现sort好像会TLE ...

刚刚试了下,发现sort并不会导致TLE。

导致TLE的竟然是检查循环里面的除法向上取整的写法。

TLE写法:

t = diff / k + ((diff%k==0)?0:1);

AC写法:

t = (diff - 1) / k + 1;

真是太可怕了...

不会是因为这个变动触发了inline吧? 手动把函数内联之后还是TLE了,排除了这种可能。

所以说... 真的可怕...

然后检查了下过的用时,上面的超时,如果用long long和long用时1900+ms,用long和int用时1600+ms ... 用sort和不用sort用时一致。

然后再测试了下,发现了更可怕的。

写法1:

t = diff / k + ((diff%k==0)?0:1);

写法2:

t = diff / k + ((diff%k>0));

写法3

t = (diff - 1) / k + 1;

写法1比写法2共多花约50ms ...

写法2用时和写法3一致。

写法1和long long结合刚好TLE ...

回去审视了下大家AC的用时,发现有500+ms AC的,也有1900+ms AC的 ...

看来这水很深,明天再研究研究别人的代码。

败了败了。没想到时间的问题居然出在流输入输出上。

迷信 sync false 和 tie 0 的我,虽然想到了这种可能,但是总以为 sync false 和 tie 0 了就和 stdio 差不了多少,毕竟自己也亲测过,以为稳的,没想到还有编译器和平台差异。

以后还是尽量只用 stdio 吧。

附上历程代码:

VJ-172735-F Github

VJ:

VJ-172735-F VJudge

参考资料:

为什么 C 语言的输入输出函数比 C++ 的输入输出流要快?

探寻C++最快的读取文件的方案

一篇不可多得的深度好文:

C++ 工程实践(7):iostream 的用途与局限

方法/平台/时间(秒) Linux gcc Windows mingw Windows VC2008
scanf 2.010 3.704 3.425
cin 6.380 64.003 19.208
cin取消同步 2.050 6.004 19.616
fread 0.290 0.241 0.304
read 0.290 0.398 不支持
mmap 0.250 不支持 不支持
Pascal read 2.160 4.668

从上面可以看出几个问题:

  1. Linux平台上运行程序普遍比Windows上快。
  2. Windows下VC编译的程序一般运行比MINGW(MINimal Gcc for Windows)快。
  3. VC对cin取消同步与否不敏感,前后效率相同。反过来MINGW则非常敏感,前后效率相差8倍。
  4. read本是linux系统函数,MINGW可能采用了某种模拟方式,read比fread更慢。
  5. Pascal程序运行速度实在令人不敢恭维。
By Donny
Last modified: 2017-07-25