這題不難,但HTTP://www.aliyun.com/zixun/aggregation/20522.html">測試資料(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這個方法到比較極致的狀態了。
#include "stdio.h"
int _n, _nodup = 0, _idx[10000000];
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};
int main(){
register int _i, _j, _x;
register int _k;
register char _c;
scanf("%d\n",&_n);
for(_i = 0; _i < _n; ++_i){
_x = 0; _j = 0;
while(_j < 7){
_c = getchar();
if(_c >= '0' && _c <= '9'){
_x = _x * 10 + _c - '0';
++_j;
}else if(_c >= 'A' && _c <= 'Y' && _c != 'Q'){
_x = _x * 10 + _mapint[_c - 'A'];
++_j;
}
}
_idx[_x]++;
while(getchar() != '\n');
}
for(_i = 0; _i < 10000000; ++_i){
_k = _idx[_i];
if(_k > 1){
printf("%03d-%04d %d\n", (_i/10000), (_i%10000), _k);
_nodup = 1;
}
}
if(_nodup == 0) printf("No duplicates.\n");
return 0;
}
編輯1: 也許進一步加速可以在回避輸出部分取餘數操作符"%"上進行。