前言
一上来就没绷住,基斯数这道题已经整了我一早上了,各种问题层出不穷接踵而至,着实折磨。
题目
用内联函数判断一个数是否为基斯数
我的思路
大纰漏
第一次尝试:
在内联函数中用动态数组解决问题
#include<stdio.h>
int sum(long long n) {
int i = 0;
while (n != 0) {
i += n % 10;
n /= 10;
}
return i;
}
inline int Keith(long long n) {
int arr[] = { (n/10) % 10,n % 10,sum(n) }, i = 0, k = 0;
while (arr[i]<=n) {
arr[i + 3] = arr[i] + arr[i + 1] + arr[i + 2];
printf("%d\n", arr[i]);
i++;
}
if (k == n)
return 1;
else
return 0;
}
int main() {
long long n = 0;
scanf("%lld", &n);
if (Keith(n) == 1)
printf("yes");
else
printf("no");
return 0;
}
从结果来看,其实函数是可以推出197的,但是系统出现报错:显示arr周围堆栈已损坏。
在CSDN上查了半天也找到的有关解释
关于VS报错:Run-Time Check Failure #2-Stack around the variable ‘arr‘ was corrupupted.(产生原因及解决办法)
运行时检查失败—变量周围的堆栈已损坏
看起来是在arr[ ]的使用上出现了问题
之后我又在vs2022上进行了实验
int main() {
int arr[]={0}, i = 1;
while (i > 0) {
arr[i] = i;
printf("%d\n", arr[i]);
i++;
}
return 0;
}
这次系统却也并未报错,不过多次运行代码并不会一直打印,而且每次停止打印时的值不一致,令我更加困惑。
接着我又进行了如下尝试
int main() {
int arr[]={1}, i = 1;
while (arr[i] >= 0) {
arr[i] = i;
printf("%d\n", arr[i]);
i++;
}
return 0;
}
这次结果直接不打印,似乎根本没有进入循环。
无奈,我只能更改了内联函数的写法:
inline int Keith(long n) {
int arr[3] = { (n / 10) % 10,n % 10,sum(n) }, i = 0, k = 0;
while (arr[2] < n) {
printf("%d\n", arr[2]);
i = arr[2];
arr[2] = arr[0] + arr[1] + arr[2];
arr[0] = arr[1];
arr[1] = i;
}
if (arr[2] == n)
return 1;
else
return 0;
}
这次终于输出正确
但是更崩溃的是,OJ系统给我判错了
(尽管提交时删去了printf(“%d\n”, arr[2]);)
最后 发现是我读题不到位
基斯数的定义是:
而我写的是只针对三位数时的情况
第二次尝试
int sum(int arr[],int n) {
int i = 0,m = 0;
while (i < n) {
m += arr[i];
i++;
}
return m;
}
int di(long long n) {
int t = 0;
while (n != 0) {
t++;
n /= 10;
}
return t;
}
int main() {
long long n = 0;
scanf("%lld",&n);
//printf("%lld\n",n);
int c = di(n);
int arr[c];
int i = di(n)-1;
long long m = n;
while (m != 0) {
arr[i] = m % 10;
printf("%d\n",arr[i]);
m /= 10;
i--;
}
int s = sum(arr, di(n));
i = 0;
printf("%d\n",s);
while (s < n) {
while (i < di(n)-1) {
arr[i] = arr[i + 1];
i++;
}
arr[di(n)-1] = s;
s = sum(arr, di(n));
printf("%d\n",s);
i = 0;
}
if (s == n)
printf("Yes");
else
printf("No");
return 0;
}
终于成功了【泪目】,整整搞了9次
遇到的问题
这次虽然成功了,但是还是反应出来非常多的问题:
1.对于动态数组arr[ ],不同编译器的处理方式不同:
这是这道题之所以折磨我这么久的主要原因
在VS2022里
![在这里插入图片描述](https://img-blog.csdnimg.cn/9c80d135623d401badef9ab3daae5518.png)
满屏都是对int arr[];
的报错,
但是当我换用CodeBlocks时却能成功编译.
2.对数组使用的不熟练
例如sum函数,在调用时经常误写成int s = sum(arr[], di(n));
int sum(int arr[],int n) {
int i = 0,m = 0;
while (i < n) {
m += arr[i];
i++;
}
return m;
}
int s = sum(arr, di(n));
为啥没用内联函数也能过?(狗头)
基斯数
最后,补上基斯数的相关知识:
1.10进制基斯数有:14、19、28、47、61、75、197、742、1104、1537、2208、2580、3684、4788、7385、7647、7909、31331、34285、34348、55604、62662 、86935、93993、120284、 129106、147640、156146、174680、183186、298320、355419、694280、925993、1084051、7913837、11436171、33445755、44121607、1 29572008、251133297……
2.有关基斯数的学术报告