我刚发现sprintf()
(c ++库函数)的奇怪之处。
看看这两个解决方案
他们之间的唯一区别是,我用了
sprintf(a,"%d%c",n,'\0');
在TLE解决方案中,
在AC解决方案中,我将sprintf()
替换为
sprintf(a,"%d",n);
您还可以观察到ACed解决方案仅需0.01秒和2.8MB内存 但TLE解决方案大约需要11.8MB check here
另外还有一个让TLE运行的程序在IDEONE中以极端输入数据运行 这是CODECHEF本身的错误
有人请解释一下,这是一个错误,或者在这里发生了一些相当大的未知操作。
提前致谢。
答案 0 :(得分:0)
首先,代码中的差异<{>>不与sscanf
,但sprintf
。代码的差异解释了:
--- ac.c 2014-05-24 14:31:18.074977661 -0500
+++ tle.c 2014-05-24 14:30:52.270650109 -0500
@@ -4,7 +4,7 @@
string mul(string m, int n){
char a[4];
-sprintf(a,"%d",n);
+sprintf(a,"%d%c",n,'\0');
int l1 = strlen(a);
//printf("len : %d\n",l1);
int l2 = m.length();
其次,通过使用%c
和'\0'
明确打包字符串,您将减少可以存储在1中的整数的大小。您需要检查sprintf的返回值。 man printf:
成功返回后,这些函数会返回打印的字符数(不包括用于结束输出到字符串的尾随&#39; \ 0;用于结束输出到字符串)。
在您的情况下,您最有可能在a[4]
字符串的末尾写作并且遇到未定义的结果。使用a[4]
,您只有999\0
的空间。明确添加%c
+ '\0'
后,您将其减少为99\0\0
。如果您的号码超过99,那么sprintf将写入超出字符串末尾的内容,因为您明确地打包了一个额外的&#39; \ 0&#39;。在原始情况下sprintf(a,"%d",n);
999可以存储而不依赖于sprintf来附加&#39; \ 0&#39;作为[3]。
使用n = 9999
进行测试,sprintf仍会将数字存储在a中,但会返回超出可用空间5
的{{1}},这意味着您的代码行为是骰子 - 在那一点滚动。