1010题—企业发放奖金
首先想到对于分段函数的求值,直接使用else-if语句判断求解问题,else-if的语法结合本题代码如下:
if(boolean_expression 1)
{
/*表达式为1执行该语句*/
}
else if(boolean_expression 2)
{
/*表达式为1执行该语句*/
}
else if(boolean_expression 3)
{
/*表达式为1执行该语句*/
}
...
else{
/*以上表达式都不为真时,执行*/
}
我使用时候省略了{},tab一个缩进也可以代表是对应的语句。
在我提交过后,感觉我的代码问题仅仅能解决问题。else-if级联太多,耗时太多以及整数太大影响观感,以及使用其他的方法如switch-case语句。对于其他人的代码学习之后,我的代码和思路可以改进的是:
- 整数太大:较多人使用一个变量除以10000将整数缩小;我最喜欢的是一个使用宏定义N=100000,这点是我没想到的,宏定义在代码运行中可以直接文本替换。我这里两种都敲了一遍,需要注意的是当选择将整数缩小的时候,计算结果可能是浮点数而非整数,最后输出结果时如果想更精确的数值,可以再把数值放大或者输出格式是浮点数。
宏定义的语法如下:
#define N 100000(使用过程中注意带#,是define而不是def,末尾没有 ; )
#define N 100000
- 耗时太多:不使用else-if级联,减少判断,可以使用switch-case语句;递归实现或者是for循环数组,显然后面两种方法更巧妙。这里我也都一一进行了实现。
递归实现
对于递归实现如下:
因为在随着金额的不断增加,每个范围内的利润计算方式是一样的,所以对于增加的金额只需要计算增加部分的利润加上之前对于范围取最大值的利润即可,但是实际上也做了同样的判断,只不过代码的可读性增强,看起来没有那么冗余。
#define N 100000
int money(int i){//这是计算利润的函数,参数是i
int sum;
if(i <=N)
sum = 0.1*i;
else if(i>N && i<=2*N)
sum = (i-N)*0.075 + money(N);
else if(i>2*N && i<=4*N)
sum = (i-2*N)*0.05 + money(2*N);
else if(i>4*N && i<=6*N)
sum = (i-4*N)*0.03 + money(4*N);
else if(i>6*N && i<=10*N)
sum = (i-6*N)*0.015 + money(6*N);
else
sum = (i-10*N)*0.01 + money(10*N);//参考的其他人代码是直接每个路径return计算所得的利润,但是程序要保持尽可能的单一出口,所以我利用变量储存该计算值,确保程序是单一出口。
}//接下来只需要在main函数中调用函数即可。
数组方法
这个方法是我觉得代码最精简的,看上去非常简单而且思路巧妙,涉及的知识点也很多,能够在这个题目里巩固到很多知识点。
#include <stdio.h>
#define WAN 100000
int main () {
double i;
int j;
double bonus;
double jiedian[] = {1*WAN,2*WAN,4*WAN,6*WAN,10*WAN};
double ratio[] = {0.1,0.075,0.05,0.03,0.015,0.01};//存入数组
printf("please enter your profit:");//提示输入内容
scanf("%lf",&i);
for(j = 0;j<5;j++){
if(i<=jiedian[j]){
bonus+=i*ratio[j];//计算溢出部分的利润
break;
}else{
bonus+=jiedian[j]*ratio[j];//计算固定范围的利润
i-=jiedian[j];
}
}
// 保留两位小数
printf("%.2lf",bonus);
return 0;
}
将分段的金额和范围内的利率存入数组,for循环遍历数组,嵌套if语句判断,break为计算完成时跳出循环。实际上是if语句的两种支路不是二选一而是都参与计算,只不过将计算的利润分为两部分,是非常巧妙的思想。