C++快速解决2023年重庆中考填空压轴题的最后一空

笔者参加了2023年重庆中考。

这次中考的数学比较简单,笔者如愿以偿,拿到了149分。不过笔者在填空压轴题上花了比较久的时间,因此在考完后的闲暇时间里,试图用C++解决这道题,发挥电脑特别能算的优势,暴力解决。

先看题目:

 (图片不是很清晰,望谅解)

第一空十分简单,答案为4312.

第二空稍微有一点难度,答案为8165.(严谨的数学推导过程就不展示了)

下面,让我们来设计解决这道题的程序。

程序将会由三个功能组成:

1.判断一个数是否为递减数;

2.生成所有的递减数;

3.生成满足“前三个数字组成的三位数\overline{abc}与后三个数字组成的三位数\overline{bcd}的和能被9整除”的所有递减数.

接下来,我们一个个地实现这些功能。

1.判断一个数是否为递减数

这可以用一个bool类型的函数,输入需要判断的数(int类型,这里设它为num),返回true或者false。

bool diJianShu(int num){
    
}

大概就长成这个样子,需要的时候调动diJianShu这个函数就行了。

接着往里面塞代码:

如果一个数是递减数,它必须满足以下几个条件:

一、它是个四位自然数。

这意味着它要介于1000~9999之间,也就是说它不能小于1000或大于9999.

如果它小于1000或大于9999,就返回false,反之接着判断其他条件是否符合。

//判断这个数是否为四位自然数
if (num < 1000) {
	return false;
}
else if (num > 9999) {
	return false;
}

二、各数位上的数字均不相等;

三、各数位上的数字均不为零;

让我们先想办法获取这个四位数的各个数位上的数字。

如题,设这个四位数千位上的数字为a,百位上的数字是b,十位上的数字是c,个位上的数字是d。

根据C++的 bug 特性,两个int类型的整数数据之间做除法运算,得到的结果总还会是int类型的整数,并且这个结果是真实结果向下舍的。比如8165÷1000,C++会认为它的结果是8.

因此a就很好获取了:int a = num / 1000;

以此类推,b、c、d也很好获取。

b是第二位数字,也就是前两位组成的数字去掉第一位数字:int b = num / 100 - 10 * a;

c是第三位数字,也就是前三位组成的数字去掉第一位和第二位数字:int c = num / 10 - 100 * a - 10 * b;

d是第四位数字,也就是用num减去1000a减去100b减去10c:int d = num - 1000 * a - 100 * b - 10 * c;

这四个数字首先都不能等于0.

//判断各个数位上的数字是否均不为零
if (a == 0 || b == 0 || c == 0 || d == 0) {
	return false;
}

接着该如何判断各个数位上的数字是否互不相等呢?这需要将四个数位上的数字逐一比较大小,而这是有技巧的,以下是一种示例:

第一次,将a与b、c、d比较,有相同的就不是递减数,没有相同的就接着往下比较,这不难理解。

第二次,将b与c、d比较,与第一次类似,有相同的就不是递减数,没有相同的就接着往下比较(为什么不把b与a比较大小呢?因为这步已经在第一次比较中做过了)。

第三次,将c与d比较。

如果经过这三次比较发现有两个数位上的数字相同,则它不是递减数,反之接着判断其他条件是否符合。

//判断各个数位上的数字是否互不相等且均不为零
else {
	//获取各个数位上的数字
	int a = num / 1000;
	int b = num / 100 - 10 * a;
	int c = num / 10 - 100 * a - 10 * b;
	int d = num - 1000 * a - 100 * b - 10 * c;
	//判断各个数位上的数字是否均不为零
	if (a == 0 || b == 0 || c == 0 || d == 0) {
		return false;
	}
	//各个数位上的数字是否互不相等
	else if (a == b || a == c || a == d) {
		return false;
	}
	else if (b == c || b == d) {
		return false;
	}
	else if (c == d) {
		return false;
	}

四、满足\overline{ab}-\overline{bc}=\overline{cd}

事实上,\overline{ab}=10a+b\overline{bc}=10b+c\overline{cd} = 10c+d.

因此如果这个数满足了\overline{ab}-\overline{bc} = 10a + b - 10b - c = 10c + d,它就是递减数,反之则不是。

else {
	//判断是否满足递减数的条件
	if (10 * a + b - 10 * b - c == 10 * c + d) {
		return true;
	}
	else {
		return false;
	}
}

如此,这个判断的函数就搞定了:

//判断一个数是否为递减数的函数(返回true或false)
bool diJianShu(int num) {
	//判断这个数是否为四位自然数
	if (num < 1000) {
		return false;
	}
	else if (num > 9999) {
		return false;
	}
	//判断各个数位上的数字是否互不相等且均不为零
	else {
		//获取各个数位上的数字
		int a = num / 1000;
		int b = num / 100 - 10 * a;
		int c = num / 10 - 100 * a - 10 * b;
		int d = num - 1000 * a - 100 * b - 10 * c;
		//判断各个数位上的数字是否均不为零
		if (a == 0 || b == 0 || c == 0 || d == 0) {
			return false;
		}
		//各个数位上的数字是否互不相等
		else if (a == b || a == c || a == d) {
			return false;
		}
		else if (b == c || b == d) {
			return false;
		}
		else if (c == d) {
			return false;
		}
		else {
			//判断是否满足递减数的条件
			if (10 * a + b - 10 * b - c == 10 * c + d) {
				return true;
			}
			else {
				return false;
			}
		}
	}
}

此时再设计一个交互界面就行了。

cout << "请输入想要判断的数:";
//接收用户输入
cin >> num;
if (diJianShu(num)) {
	cout << num << "是递减数" << endl;
}
else {
	cout << num << "不是递减数" << endl;
}
cout << "请再次输入想要进行操作的序号:";

2.生成所有的递减数

思路就是从1000到9999一一枚举,每个数字都进行判断,满足递减数的条件就输出,不满足就判断下一个数。

for (int i = 1000; i < 10000; i++) {
	if (diJianShu(i)) {
		cout << i << endl;
	}
}
cout << "请再次输入想要进行操作的序号:";

枚举的时候要使用for循环。

3.生成满足“前三个数字组成的三位数\overline{abc}与后三个数字组成的三位数\overline{bcd}的和能被9整除”的所有递减数.

同样也是从1000枚举到9999,判断它是否同时满足以下两个条件:

①它是递减数;

②它前三个数字组成的三位数\overline{abc}与后三个数字组成的三位数\overline{bcd}的和能被9整除.

当且仅当两个条件都满足时,这个数是题目所要求的递减数。

最后输出的只有三个数:5413,7248,8165。很明显,8165就是这道题的答案。

for (int i = 1000; i < 10000; i++) {
	if (diJianShu(i)) {
        //获取各个数位上的数字
		int a = i / 1000;
		int b = i / 100 - 10 * a;
		int c = i / 10 - 100 * a - 10 * b;
		int d = i - 1000 * a - 100 * b - 10 * c;
        //根据题目的条件进行判断
		if ((100 * a + 10 * b + c + 100 * b + 10 * c + d) % 9 == 0) {
			cout << i << endl;
		}
	}
}
cout << "请再次输入想要进行操作的序号:";

由此观之,三个功能我们都已实现,用一个死循环while(1){}套在外面就可以一直根据用户要求进行新的操作了。

源代码如下:

#include<iostream>
using namespace std;
//判断一个数是否为递减数的函数(返回true或false)
bool diJianShu(int num) {
	//判断这个数是否为四位自然数
	if (num < 1000) {
		return false;
	}
	else if (num > 9999) {
		return false;
	}
	//判断各个数位上的数字是否互不相等且均不为零
	else {
		//获取各个数位上的数字
		int a = num / 1000;
		int b = num / 100 - 10 * a;
		int c = num / 10 - 100 * a - 10 * b;
		int d = num - 1000 * a - 100 * b - 10 * c;
		//判断各个数位上的数字是否均不为零
		if (a == 0 || b == 0 || c == 0 || d == 0) {
			return false;
		}
		//各个数位上的数字是否互不相等
		else if (a == b || a == c || a == d) {
			return false;
		}
		else if (b == c || b == d) {
			return false;
		}
		else if (c == d) {
			return false;
		}
		else {
			//判断是否满足递减数的条件
			if (10 * a + b - 10 * b - c == 10 * c + d) {
				return true;
			}
			else {
				return false;
			}
		}
	}
}
int main() {
	cout << "如果一个四位自然数(abcd)的各数位上的数字互不相等且均不为0,满足(ab)-(bc)=(cd),那么称这个四位数为“递减数”,例如:四位数4129,41-12=29,∴4129 是“递减数”.又如:四位数5324,53-32=21≠24,所以5324 不是“递减数”." << endl;
	cout << "1.判断一个数是否为递减数;" << endl;
	cout << "2.生成所有的递减数;" << endl;
	cout << "3.生成满足前三个数字组成的三位数(abc)与后三个数字组成的三位数(bcd)的和能被9整除的递减数." << endl;
	cout << "请输入你想要进行的操作的序号:";
	int a, num;
	//a为用户想要进行的操作的序号,num为用户想要判断时输入的数字
	while (1) {
		//输入想要进行的操作的序号
		cin >> a;
		//根据序号的不同,选择不同的代码执行
		if (a == 1) {
			cout << "请输入想要判断的数:";
			//接收用户输入
			cin >> num;
			if (diJianShu(num)) {
				cout << num << "是递减数" << endl;
			}
			else {
				cout << num << "不是递减数" << endl;
			}
			cout << "请再次输入想要进行操作的序号:";
		}
		else if (a == 2) {
			for (int i = 1000; i < 10000; i++) {
				if (diJianShu(i)) {
					cout << i << endl;
				}
			}
			cout << "请再次输入想要进行操作的序号:";
		}
		else if (a == 3) {
			for (int i = 1000; i < 10000; i++) {
				if (diJianShu(i)) {
					//获取各个数位上的数字
					int a = i / 1000;
					int b = i / 100 - 10 * a;
					int c = i / 10 - 100 * a - 10 * b;
					int d = i - 1000 * a - 100 * b - 10 * c;
					//根据题目的条件进行判断
					if ((100 * a + 10 * b + c + 100 * b + 10 * c + d) % 9 == 0) {
						cout << i << endl;
					}
				}
			}
			cout << "请再次输入想要进行操作的序号:";
		}
		else {
			cout << "非法输入,请重新输入:";
		}
	}
	system("pause");
	return 0;
}

如有错误,请在评论区斧正。谢谢大家!

网盘链接:阿里云盘分享

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值