题目描述
从2018年1月1日开始,小明每天给Angela发一个红包,红包金额的单位为元(¥),其中:金额的整数部分与月份相同,金额的小数部分与日期相同。具体的红包金额如下所示:
现在请你计算:截止于2018年某个具体的日期,小明发给Angela的红包金额总数是多少?
输入
2018年的某个日期,格式为yyyy m d,如:2018 5 19
其中的年份yyyy固定为2018,月份m、日期d为2018年某个合理的日期(即:不会出现2月29日、6月31日或负数的月份日期以及月份大于12或日期大于31等不合理的情况)
输出
小明发给Angela的红包金额总数,单位为元,保留两位小数
样例输入 Copy
【测试样例1】 2018 1 1 【测试样例2】 2018 5 19
样例输出 Copy
【测试样例1】 1.10 【测试样例2】 435.78
这一题主要难在对题意的理解和对数据的敏感。
本人的整体思路是:先分别单独计算小数点左边的金额也就是“元”和右边的也就是“角”,最后把角转换为元和小数点左边的元求和。
但这种思路有个很容易忽略的盲区:当号数是从1号到9号时小数部分的金额是0.1到0.9,也就是从1角开始每次加1角到9角,但到第10号时显然变成0.10,也就是1角,而不是想当然的10角。
所以在进行小数部分金额的加算时,应该加上判断条件
if(号数 >= 10)
sumflo = (double)号数/10
//这里因为是写在for循环体里面的,号数是整型变量,所以做了个强制类型转换,否则小数会被丢掉
完整代码如下:
#include <stdio.h>
int main() {
int y, m, d;
scanf("%d%d%d", &y, &m, &d);
double sumflo = 0;
double sumint = 0;
for (int i = 1; i < m; i++) {
switch (i) {
case 1:case 3:case 5:case 7:case 8:case 10:case 12://对31天大月的处理
for (int j = 1; j <= 31; j++) {
sumint += i;
if (j >= 10) {
sumflo += ((double)j / 10);
}
else
sumflo += j;
}
break;
default:
if (i == 2) {//对28天二月的处理
for (int j = 1; j <= 28; j++) {
sumint += i;
if (j >= 10) {
sumflo += ((double)j / 10);
}
else
sumflo += j;
}
}
else {对30天小月的处理
for (int j = 1; j <= 30; j++) {
sumint += i;
if (j >= 10) {
sumflo += ((double)j / 10);
}
else
sumflo += j;
}
}
}
}
//以上部分都是处理有完整一个月的情况,现在把单独的不满一个月的剩余部分处理完(比如输入2018 5 19时,先整体处理前面完整的4个月,然后再处理5月的19天)
sumint += (m * d);
for (int i = 1; i <= d; i++) {
if (i >= 10) {
sumflo += ((double)i / 10);
}
else
sumflo += i;
}
double result = sumint + sumflo / 10;
printf("%.2f", result);
}