C++不使用公式和选择、循环求阶和

今天让我来继续挑战题目的权威。


题目

求1+2+3+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。


解题经历

题目的意思很明确了,(明码中)不能出现选择结构循环结构(不严谨的说法),也用不了等差数列求和公式 S n = n ⋅ ( a 1 + a n ) ÷ 2 S_n = n \cdot (a_1 + a_n) \div 2 Sn=n(a1+an)÷2)。那么,就得想想除了循环,还有什么东西(在流程图中)是循环结构体——函数递归
于是,初步代码就有了:

# include <iostream>
int n, sum;
int x (int a);
int main (){
	scanf("%d", &n);
	printf("%d", x(n+1));
	return 0;
}
int x (int a){
	--a;
	x(a);
	return sum += a;
}

现在,循环结构体是有了,但是这是一个没有终止的无限循环;我们都知道,在流程图中,想要跳出循环一般都会有一个选择结构,因此就得想办法在不使用if的情况下,使程序拥有判断能力
于是,我在脑海中遍历了我所知道的所有语法及知识点,历经2.5h(实际时间也接近1h了)我可算联想到了——短路语句!题目中只说不能使用if,没说不能使用逻辑表达式啊!

(可能是)所有(编程语言中的)逻辑表达式公有的特性:

  1. 逻辑与是前后两个表达式都为true,最终的结果才为true;而程序运行时,如果发现第一个表达式为false,那么它鸟都不鸟第二个表达式,最终结果直接为false
  2. 逻辑或是前后两个表达式其中一个为true,整个表达式就都为true;而程序运行时,如果发现第一个表达式为true,那么它鸟都不鸟第二个表达式,最终结果直接为true

因此,只需要把引用函数放在第二个表达式上,当第一个表达式为0时,就可以跳出循环了!
而这个0是怎么得到的呢?很简单,我们的变量a每递归一次,就减一,而正好我们就是要一直累加到0累加到1和累加到0是一样的),所以第一个表达式就是a了。

# include <iostream>
int n, sum;
int x (int a);
int main (){
	scanf("%d", &n);
	printf("%d", x(n+1));
	return 0;
}
int x (int a){
	--a;
	a && x(a);
	return sum += a;
}

最后还是来浅浅的解释一下代码:

第10行就是每递归一次,参数减一(因为第一次引用函数时参数也会减一,所以在第6行参数提前先加一);
第11行前面说了,这个逻辑与是判断的用途:如果a为(递归(或累加)到)0了,那么第二个表达式——递归步骤就被短路掉了;然后就来到第12行开始不断返回并累加数据,最后返回到第6行输出。


总结

最后不得不说这道题考的太灵活了,首先需要摸清题目的本质(流程图步骤),然后再去找可以替代原始语句的方法,最后才是编程运维。
我们以后做题也要学着举一反三,这里不仅仅是数量上的练习,更是方法上的探索,一定要清楚思维的底层逻辑,思考不同语句、语法的异同。你的思维活了,题目考的就死了;你的思维死了,题目考的可就灵活了。


花钱学编程浪费钱,还不一定讲的好;
还不如到Noi官网自学,免费回放课,讲的还详细!
连接:https://www.noi.cn/xw/2020-05-13/715542.shtml
纯个人推荐,(与本篇文章无关。)


2024.3.16补充

这样写舒服一些,还更好理解。

#include<cstdio>
int x, d;
int f(int n){
	d+=n;
	n && f(n-1);
}
int main(){
	scanf("%d", &x);
	f(x);
	printf("%d", d);
	return 0;
}

至于为什么int类型函数没有写返回值,详见这篇文章


  • 23
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值