题目:
小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行,递推最大的特点就是按部就班,一步一步的执行,最明显表现就是 循环 。
关于递归和递推的其他不同之处,比如在有些地方为什么不能用递推而可以用递归,就请伙伴们另问高明吧(其实我自己都没搞的很明白)。