小宋银行的贷款漏洞
题目描述
有一天小宋买彩票中了奖,他不想直接花出去,于是他开起了一家银行做起了贷款生意。他的贷款策略是这样的:
- 贷款金额可以看做是一个整数x( 0 < x ⩽ 2 31 − 1 0<\mathrm{x}\leqslant 2^{31}-1 0<x⩽231−1),x的整数形式的表达又可以是 a 1 , a 2 , a 3 ⋯ a n \mathrm{a}_1,\mathrm{a}_2,\mathrm{a}_3\cdots \mathrm{a}_{\mathrm{n}} a1,a2,a3⋯an,其中整数 a i ( i ∈ [ 1 , n ] ) , \mathrm{a}_{\mathrm{i}}\left( \mathrm{i}\in \left[ 1,\mathrm{n} \right] \right) , ai(i∈[1,n]),且 a i ∈ [ 0 , 9 ] , \mathrm{a}_{\mathrm{i}}\in \left[ 0,9 \right] , ai∈[0,9], ai的表示的意义就是x从左到右数的第i为数字;
- 贷款时间 t ∈ [ 0 , + ∞ ] , \mathrm{t}\in \left[ 0,+\infty \right] , t∈[0,+∞], 且为整数;
- 贷款利率为
a
1
t
\frac{\mathrm{a}_1}{\mathrm{t}}
ta1 ,可以看出贷款利率和金额与时间都有关系,但是如果借贷时间小于一年则无利率;
注:可以发现一个奇怪的事情就是小宋银行最大的漏洞在于随着时间的增长利息是有上限的。
小宋同学最近放了寒假没时间处理接待事物,所以我们帮他计算一下吧。
输入
生意火爆所以我们需要先输入T组数据:
1 .每组数据有x、t组成,其中x的范围问题描述已告知:
2 .注:为了避免数据过大,t的形式有两种:
1.整数数值类型:
t
∈
[
1
,
30
]
;
\mathrm{t}\in \left[ 1,30 \right] ;
t∈[1,30];
2.字符串类型:
t
∈
{
“
Z
E
R
O
”
,
“
+
I
N
F
”
}
,
\mathrm{t}\in \left\{ \left. \mathrm{“ZERO”},\mathrm{“}+\mathrm{INF”} \right\} \right. ,
t∈{“ZERO”,“+INF”}, 前者可理解为无利率,后者可理解为借款无限时间(因为上面我们说到了利息看起来是有上限的,所以有人钻了空子);
输出
因为存在借贷关系,所以我们需要标记熟悉的#Case i :之后输出相应的连本带利须还的金额
样例输入
3
100 1
1 ZERO
5 +INF
样例输出
#Case 1 : 200
#Case 2 : 1
#Case 3 : 742
提示
数据组数T<10,只需输出整数(向下取整)
求解思路
根据样例输入的格式有数字型,有字符串型,我们可以统一使用字符数组来储存,其次理解题意,可得到公式为 存 储 后 金 额 = 存 储 前 金 额 ∗ ( 1 + 最高位的数 时间 ) 时间 存储后金额=存储前金额*(1+\frac{\text{最高位的数}}{\text{时间}})^{\text{时间}} 存储后金额=存储前金额∗(1+时间最高位的数)时间 。通过while循环我们可以求出a1,根据输入的时间格式不同,大致可以分为三种:数值、ZERO、+INF。可分别采用if函数求解
代码如下:
#include<stdio.h>
#include<math.h>
int main()
{
int h = 1;//每个案例序号
double e[10];//存储e的多次方
e[1] = 2.718281828459045;//位数需要足够多才通过更多案例
for (int i = 2; i <= 9; i++)
{
e[i] = pow(e[1], i);//pow函数求e的n次方
}
long long m;
scanf("%lld", &m);//案例数目
while (m--)
{
long long x;
char t[5];
scanf("%lld", &x);//存储金额
getchar();
scanf("%s",t);//存储期限(以字符串形式存储)
if (t[0] == '+')
{
int a1 = 0;
double k = x;
while (x > 0)
{
a1 = x % 10;
x = x / 10;
}//求存储金额的最高位
long long int temp = k * e[a1];//运用常用极限
printf("#Case %d : %lld\n",h, temp);
}
if (t[0] == 'Z')
{
printf("#Case %d : %lld\n",h,x);
}
if (t[0] >= '0' && t[0] <= '9')
{
int a = x;//提前需要存储一个一样的,后续计算会改变x值,方便最后计算时使用
double a1;
while (x > 0)
{
a1 = x % 10;
x = x / 10;
}
int i = 0, sum = 0;
while (t[i] != '\0')
{
sum = sum * 10 + (t[i] - '0');
i++;
}//将字符类型转化为数值类型
double sum1 = a * 1.0;
sum1 = a * pow(1 + (a1 * 1.0) / sum, sum);//套公式(存储后金额=存储前金额*(1+最高位的数/时间)的时间次方
long long loop = sum1;
printf("#Case %d : %lld\n", h, loop);
}
h++;
}
return 0;
}