我在C ++部分已经看到很多问题。他们中的大多数人都建议使用uint64_t, unsigned long long
而我已经尝试了
我输入10 ^ 18作为其最大输入。 但正在处理的数字将作为一些垃圾值返回。
我将其输入为111111111111111110
,
在我将其除以10^(step-1)
并将其乘以10^(step-1)
时的行
Right Now In 111111111111111103
Right Now In 111111111111111104 //But it should be 111111111111111100 and then -- to decreas one more
这种方法适用于较小的值。但是没有更多的投入
#include<stdio.h>
#include<stdbool.h>
#include<stdlib.h>
#include<math.h>
#include<stdint.h>
#include<inttypes.h>
int step = 0;
bool isTidy(uint64_t n){
step++;
if(n < 10) return true;
int lastNumber = n % 10;
int secondLastNumber = ((n - lastNumber)/10) % 10;
return (lastNumber >= secondLastNumber) && isTidy((n - lastNumber)/10);
}
int main(){
char* inputString;
uint64_t testNumber;
int numberOfTestcases;
int iterator = 1;
scanf("%d", &numberOfTestcases);
while(numberOfTestcases --> 0){
scanf("%"SCNu64,&testNumber);
do{
step = 0;
if(isTidy(testNumber)){
printf("Case #%d: %"PRIu64"\n",iterator++, testNumber);
break;
}
printf("Right Now In %"PRIu64"\n",testNumber);
testNumber /= pow(10,step - 1);
testNumber *= pow(10,step - 1);
printf("Right Now In %"PRIu64"\n",testNumber);
}while(testNumber --> 0);
}
return 0;
}
编辑:试图澄清问题。并修复了扫描输入问题
答案 0 :(得分:2)
第二个scanf()
中的转换说明符错误。你应该:
scanf("%"SCNu64,&testNumber);
此外,其中一个printf()
语句中有一个逗号:
printf("Right Now In %"PRIu64"\n",testNumber);
最好启用编译器警告来帮助捕获这些简单的错误。我总是至少编译:
gcc -Wall -Wextra -Wpedantic
如果没有启用警告,发布的代码将在没有警告的情况下编译。
大输入的附加问题可以追溯到pow()
函数,该函数返回double
,而不是uint64_t
。一种解决方案是用对另一个返回pow()
的函数的调用替换对uint64_t
的调用。这是一个例子,虽然这不是长期最有效的实现:
uint64_t mypow(uint64_t base, unsigned exp)
{
uint64_t res = 1;
while (exp--) {
res *= base;
}
return res;
}
答案 1 :(得分:1)
我不明白你使用PRIu64的原因。
我已经从Google CodeJam完成了这个问题,使用long long就可以使用简单的scanf(&#34;%lld&#34;)就足够了。
<强>编辑强>
由于我的回答显然不够好,这里有一些说明,因为第32行,你在打印时会得到垃圾值:
printf("Right Now In %"PRIu64,"\n",testNumber);
在PRIu64之后有一个逗号,删除它,所有值都将正确打印。如果您因其他原因(例如无限循环)而无法获得RTE。
关于代码的问题(来自Google CodeJam),它不能处理大数(和你的例子中的无限循环),因为pow()是一个双精度,大量的精度会丢失数字,if you use your own simple pow() function,您将获得AC。