solve函数程序详解(NOIP2004 提高组)

此题为笔试题的读程序题。

题目程序代码如下:

#include
using namespace std;
int number,ndata,data[100],sum;
void solve(int s,int sign,int n){
	int i;
	for(i=s;i>number>>ndata;
	sum=0;
	for(i=0;i>data[i];
	solve(0,1,1);
	cout<

输入:1000 3 5 13 11

输出:

分析:此题是典型的for循环内插入递归调用,其实也可以转换成循环嵌套。在求解此题之前可以先缩小一下规模,寻找程序运行的方式。只要找到这个子问题的方式,那么这个题也就引刃而解了。

我们不如先把规模缩小。

​
#include
using namespace std;
int number,ndata,data[100],sum;
void solve(int s,int sign,int n){
	int i;
	for(i=s;i>number>>ndata;
	sum=0;
	for(i=0;i>data[i];
	solve(0,1,1);
      cout<

运行此程序的结果为:

1000 3 5 13 11
1.1000
1.800
1.815
2.815
2.815
1.615
2.615
2.615
1.1615
1.1539
2.1539
2.1539
1.2539
2.2539

2539

那么现在开始模拟这个程序的执行过程:

 

首先,s,sign和n的值从主函数中传到子函数solve中的初值为0,1,1。

那么第一次执行的值为:

solve(0,1,1);
for(i=0;i<3;i++)
    sum=0+1*(1000/1)=1000;

然后调用函数,由递归式solve(i+1,-sign,n*data[i])知,此时变为solve(1,-1,1*data[0])=solve(1,-1,1*5)=solve(1,-1,5);

那么第二次执行的值为:

solve(1,-1,5);
for(i=1;i<3;i++)
    sum=1000-1*(1000/5)=800;

继续调用函数,此时变为solve(2,1,5*data[1])=solve(2,1,5*13)=solve(2,1,65);

那么第三次执行的值为:

solve(2,1,65);
for(i=2;i<3;i++)
    sum=800+1*(1000/65)=815;

继续调用函数,此时变为solve(3,-1,65);

但是,此时i=3,不符合循环条件,所以递归结束。开始返回。

 

返回:(P.S:学过的递归的oler应该都知道,递归是通过栈来实现,所以可得之前计算所产生的值都被压栈了。现在所要做的操作也就是弹栈。)

现在开始返回,由于最后一次有效递归是solve(2,1,65)。所以把最后一次递归所产生的值815带到上一层solve(1,-1,5)中。

此时执行的值为:

solve(1,-1,5);
for(i=1;i<3;i++)
    sum=815-1*(1000/5)=615;

此时sum的值为615。

这一次返回有效(“有效”意为可以进行运算)。

继续返回,这一次返回到了递归”头“(solve(0,1,1))

此时执行的值为:

solve(0,1,1);
for(i=1;i<3;i++)
    sum=1000+615=1615;

但现在还不能出来。还要重新进行新一轮递归。但运算方法与上面的一样。

此时执行的值为:

solve(1,-1,5);
for(i=2;i<3;i++)
    sum=1615-1*(1000/13)=1539;

接下来i=3,不符合条件,再一次返回。

这次返回到开头(solve(0,1,1))

此时执行的值为:

solve(0,1,1);
for(i=2;i<3;i++)
    sum=1000+1539=2539;

接下来i=3,不符合条件,再一次返回。可是这一次的位置已经是在开头,没有上层在继续返回,所以整个递归函数段结束。

 

然后就是输出2539了!

 

当然,原程序的运行原理也就是这样了(同理可得),至于答案是怎么算出来的,请读者自己去算一下。(不要怪我没说题目输出是328)

你可能感兴趣的:(C++题目)