备战蓝桥---竞赛题解

牛客寒假算法集中营-第一题

关于递归和递推的描述

题目:
小a的数学基础实在太差了,以至于他只会用计算器算数。他的计算器比较特殊,只有(即加减乘除)四种运算。
经过一番周折,小a终于算出了他想要的数,但是他却忘记了最初的数是什么。不过幸运的是他记下了整个操作序列,他想请你帮他算出最初的数

输入描述:
第一行两个整数n,X,分别表示操作次数和最终的数
接下来n行表示操作序列,每行两个数opt,x若opt=1,则表示将当前数加x,若opt=2,则表示将当前数减x,若opt=3,则表示将当前数乘x,若opt=4,则表示将当前数除以x
输出描述:
一个整数表示最初的数

先闭上眼睛,仔细想想自己会怎么做,如何做,有几种方法(或思路)。

OK,献丑了
这道题在解法上有两种,但究其本源,其二者如出一宗:
解法一:递归

#include      //万能头(c++写法)
using namespace std;
typedef long long ll;
 
 void solve(ll &X, int cnt, int n) {
    if(cnt == n) return;
    ll op, x;
    cin >> op >> x;
    solve(X, cnt + 1, n);
    switch(op) {
        case 1: X -= x; break;
        case 2: X += x; break;
        case 3: X /= x; break;
        case 4: X *= x; break;
    }
}
 int main() {
    int n, op;
    ll X, x;
    cin >> n >> X;
    solve(X, 0, n);
    cout << X << endl;
    return 0;
}

这其中第九行是关键,即为递归,递归是算法里,包括算法竞赛里最重要的思想之一。其目的就在于满足条件的无限重复,直到满足另一条件(也称结束条件)。关于递归,一以下一段话大概可以作为入门吧:
山里有个庙,庙里有个和尚,和尚在给小和尚讲故事,讲的什么呢?讲的:山里有个庙,庙里有个和尚。。。。。。没有外力打断情况下就这样无休止重复下去

解法二:递推

#include       //万能头(c++写法)
using namespace std;
int n, opt[105];
long long X, x[105];
int main(){
    scanf("%d%lld", &n, &X);
    for(int i = 0; i < n; ++i){
        scanf("%d%lld", &opt[i], &x[i]);
    }
    for(int i = n - 1; i >= 0; --i){
        if(opt[i] == 4) X *= x[i];
        if(opt[i] == 3) X /= x[i];
        if(opt[i] == 2) X += x[i];
        if(opt[i] == 1) X -= x[i];
    }
    printf("%lld\n", X);
    return 0;
}

第10行,递推最大的特点就是按部就班,一步一步的执行,最明显表现就是 循环 。

关于递归和递推的其他不同之处,比如在有些地方为什么不能用递推而可以用递归,就请伙伴们另问高明吧(其实我自己都没搞的很明白)。

你可能感兴趣的:(轻松学算法,#,每日一算,#,算法入门与进阶)