题目要求
某股民投资某证券,购入该证券时间作为起始点0,当天的盈亏也定为0。假定证券价格每个交易日的变化有三档:比前一个交易日上涨1个单位,与前一个交易日持平,比前一个交易日下跌1个单位。
该股民对其持有证券的收益期望值是k个单位。即:只要该证券的价格比其购入的价格高k个单位,他就会卖出
题目分析
由题目可知,每天的交易变化为三种,分别是:-1、0、1。由用户输入交易日和期望获得的交易利益。当交易日为3时,表示三天的交易变化。且当收益提前达到期望收益时,则立刻卖出股票。
由此可知,当交易日为3时,且没有提前达到收益时,最大的循环次数为27次,则3的n次方,即交易日的n次方种可能性中找出能够达到收益的交易变化,并统计出有多少种方案。
该证券获利了结,反之如果没有达到预期的利润,他就会继续持有该证券,持有的天数最多为N个交易日。在第N个交易日,股民已经失去了耐心,无论是否达到收益预期,证券都会被该股民卖出。
解决方式:
当输入3 1 时可能出现的结果如下:
程序从day = 3 开始,当day>1时,一直嵌套直至day = 1,当day = 1时,意味着,进入最末端的判断,此时在最末端进行三次循环,并且加前两次循环的值,判断是否满足期望收入。当末端三次循环判断完成后,返回到上一层,即第二层day = 2 ,改变第二次的值后再次进入末端循环判断是否满足期望收入,当第二层的三次判断都完成后,返回到第一层,即day = 3,改变第一次的值后,再次进入第二层,第二层同样从-1开始赋值,赋值后进入末端,进行循环判断,以此类推。当循环在第二层或第一层就已经满足期望收入时,即不再进行后面的循环判断。
流程图如下:
代码如下:
一、初始化部分
#include <stdio.h>
int k; //控制数组下标
int y; //控制数组下标
int x; //控制数组下标
int a[10] = {5,5,5,5,5,5}; //数组保存满足条件的变化(为了看变化 所以赋值为5)
int count = 0; //保存有多少个满足条件
int j = 0; //存储这一次生成的序列和是否满足用户所需要的交易额
void array(int); //定义了一个自定义函数,穷举出所有的可能性
int day; //保存用户所需要的交易天数
int company; //保存用户所期望的获利单位
int arrday; //固定存放交易天数
(代码只是最基础的写出,并没有进行整理优化)
二、主函数(用于输入输出和调用)
int main() { //主函数用于调用
printf("请输入最多持有几个交易额:");
scanf("%d",&day);
printf("请输入期望获利单位:");
scanf("%d",&company);
arrday = day; //固定存放交易天数
array(company); //调用函数
printf("\n");
printf("count = %d",count); //输出
}
三、自定义函数(功能的实现)
void array(int company){
int i; //循环单位,表示第一天生成的三个数分别是-1、0、1
if (day > 1){
for (i = -1 ; i <= 1 ; i++ ){
a[day] = i; //改变当前数组的值
day = day - 1;
j = j + i; //累加趋势
if (j == company){ //如果本次循环中J等于所需的获利,则增加一次
count = count + 1; //计数加一
for (x = arrday ; x > day ; x--){
printf("%d",a[x]);
a[x] = 0;
}
printf("\n");
day = day + arrday - 1;
j = 0; //归零趋势累加
k = 0; //归零计数器
continue; //提前满足后结束本次循环,进入下一次
}
//printf ("-----)%d\n",day); //测试递归之前的day值为多少
array(company); //递归调用
//printf("%d\n",j); //测试J返回来的值
j = j - i; //减去上次判断的值
//printf("****%d\n",j); //测试当前J的值
//printf("****%d\n",day); //测试当前day的值是否传递回来
if (k == 9){ //每就是往上多回归一次(找一个不确定的值)
day = day + 1;
k = 0;
}
}
}
else{ //最后一天的三种结果生成
for (i = -1 ; i <=1 ;i++){
k = k + 1;
j =j + i;
if (j == company){ //如果满足条件,则输出
a[day] = i; //本次的结果加入到数组
for(y = arrday ; y >= day; y--) { //输出之前的每天增长趋势 (暂时性改动 y = 3 ; y >= 0 ; y--)
printf("%d", a[y]);
}
a[y+1] = 0;
printf("\n");
count = count + 1; //累加1
j = j - i; //减去本次的值
}
else{
j = j - i; //减去上次本次判断的值
}
}
//printf("****%d\n",day); //测试当前在第几层递归
day = day + 1;
//printf("---%d\n",day); //测试day是否改变
}
}
其中运用的函数的递归调用以及选择结构。并且包含了一些编码时的测试代码。
运行效果:
本次代码并不完善,只可以完成基础的几个计算,并可以完成所有的功能,后续更新出完美的代码,并且本题有多种解题思路,这种方法思路较难,不好理解。只用作作者自己的学习记录。
----2022/11/25