10_26.基斯数


前言

一上来就没绷住,基斯数这道题已经整了我一早上了,各种问题层出不穷接踵而至,着实折磨。

题目

示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。
用内联函数判断一个数是否为基斯数

我的思路

大纰漏

第一次尝试:
在内联函数中用动态数组解决问题

#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.有关基斯数的学术报告

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值