VJ 172735 F - Drying 从TLE到刚好AC再到妥妥AC 以及超级巨坑iostream
题目链接:
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:
参考资料:
为什么 C 语言的输入输出函数比 C++ 的输入输出流要快?
一篇不可多得的深度好文:
方法/平台/时间(秒) | 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 |
从上面可以看出几个问题:
- Linux平台上运行程序普遍比Windows上快。
- Windows下VC编译的程序一般运行比MINGW(MINimal Gcc for Windows)快。
- VC对cin取消同步与否不敏感,前后效率相同。反过来MINGW则非常敏感,前后效率相差8倍。
- read本是linux系统函数,MINGW可能采用了某种模拟方式,read比fread更慢。
- Pascal程序运行速度实在令人不敢恭维。