以前一次偶然的机会听说了最短代码竞赛,这两天不想干啥事,便开始做一做OJ吧,
题目见这里:http://poj.org/problem?id=1002
主要是一个字符串读取与转换,我的实现代码代码长度为651字节,39行。
#include <stdio.h> #include <map> typedef long D; typedef std::map<D,D> M; char mC[]="2223334445556667777888999"; int main(int argc, char **argv) { D n,t; M m; scanf("%d\n",&n); for(;n!=0;n--) { char s[64],c; gets(s); t=0; for(D i=0;s[i]!='\0';i++) { c=s[i]; if(c>='0'&&c<='9') t=10*t+c-'0'; if(c>='A'&&c<'Z'&&c!='Q') t=10*t+mC[c-'A']-'0'; } m[t]++; } M::iterator it=m.begin(),iE=m.end(); while(it!=iE) { if(it->second>1) { n++; printf("%03d-%04d %d\n",it->first/10000,it->first%10000,it->second); } it++; } if(!n) printf("No duplicates.\n"); return 0; }
讲解一下上述代码利用了以下几个C++的语法特性:
(1)map类,可以对每个标准电话号码进行快速的统计和计数,插入新的数据非常方便。
(2)m[t]++; 这个语句详细的解释可以参看《C++ Primer》中关于map类模版的介绍。
如果t不在map中,则新增一个元素,m[t]的值会初始化为0,然后进行一个自增操作,即计数值为1。
否则,m[t]的值由原来的值加1。
(3)typedef定义,主要是减少一点代码长度;
(4)OJ需要注意的问题,刚开始没有注意可能没有重复项目,中间又因为没考虑Q会出现在测试数据中所以一直错误。
最后附图代码长度与状态:
2013-7-29更新:
最后也顺便附上一个C语言版本,和上面的类似,代码也更加简短了,537字,效率也相对更高,不过内存使用有点多了(C++也可以不用map类进行一样的改写):
#include <stdio.h> typedef long D; #define z 10000000 D m[z]={0}; char mC[]="2223334445556667777888999"; int main() { D n,t,i; scanf("%d\n",&n); for(;n!=0;n--) { char s[64],c; gets(s); t=0; for(i=0;s[i]!='\0';i++) { c=s[i]; if(c>='0'&&c<='9') t=10*t+c-'0'; if(c>='A'&&c<'Z'&&c!='Q') t=10*t+mC[c-'A']-'0'; } m[t]++; } for(i=0;i<z;i++) { if(m[i]>1) { n++; printf("%03d-%04d %d\n",i/10000,i%10000,m[i]); } } if(!n) puts("No duplicates."); return 0; }代码长度与运行结果如下,运行时间还是会受到一些非稳定因素的干扰的。有时候时间短一点~~