http://poj.org/problem?id=1002
这题不难,但测试数据(http://www.ntnu.edu.tw/acm/ProblemSetArchive/B_US_EastCen/1999/index.html)很野蛮,有好几个是1百万行的测试数据。
一开始没注意到2000毫秒的限制,结果第一个版本的程序写成了许多函数,尽量避免全局变量,还用了动态内存分配和struct。后来发现总是超时。网上查了别人的解答,发现要过的话就必须做比较强的输入格式假设,然后不要管太多style的原则,尽量在一个main里完成。另外输入输出不要用流,流好像有点慢。
网上(http://www.cnblogs.com/mobileliker/archive/2013/05/26/3099748.html)的一个比较好的结构是直接开一个1千万的稀疏数组来存0-9999999的条形图计数,省去nlgn的排序。内存限制不紧,有65536KB,这个数组整形的话是4千万字节,大约35000K字节,所以内存够用。
这个解法另一个值得借鉴的地方是他读入的方式,他读入用的是一个字符一个字符地读,看上去很散漫,但确实节约了一次读一行再iterate每个字符的重复工作。i/o的效率是过的关键
我的解答是借鉴了上面这个办法的,和他的解法也比较像,说明确实这么写是push这个方法到比较极致的状态了。
</p>
<p>#include "stdio.h"<br />
int _n, _nodup = 0, _idx[10000000];<br />
int _mapint[25] = {2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,0,7,7,8,8,8,9,9,9};<br />
int main(){<br />
register int _i, _j, _x;<br />
register int _k;<br />
register char _c;<br />
scanf("%d\n",&_n);<br />
for(_i = 0; _i < _n; ++_i){<br />
_x = 0; _j = 0;<br />
while(_j < 7){<br />
_c = getchar();<br />
if(_c >= '0' && _c <= '9'){<br />
_x = _x * 10 + _c - '0';<br />
++_j;<br />
}else if(_c >= 'A' && _c <= 'Y' && _c != 'Q'){<br />
_x = _x * 10 + _mapint[_c - 'A'];<br />
++_j;<br />
}<br />
}<br />
_idx[_x]++;<br />
while(getchar() != '\n');<br />
}</p>
<p> for(_i = 0; _i < 10000000; ++_i){<br />
_k = _idx[_i];<br />
if(_k > 1){<br />
printf("%03d-%04d %d\n", (_i/10000), (_i%10000), _k);<br />
_nodup = 1;<br />
}<br />
}</p>
<p> if(_nodup == 0) printf("No duplicates.\n");<br />
return 0;<br />
}<br />
</p>
编辑1: 也许进一步加速可以在回避输出部分取余数操作符"%"上进行。