问题描述
试题编号: 201612-2
试题名称: 工资计算
时间限制: 1.0s
内存限制: 256.0MB
问题描述
小明的公司每个月给小明发工资,而小明拿到的工资为交完个人所得税之后的工资。假设他一个月的税前工资(扣除五险一金后、未扣税前的工资)为S元,则他应交的个人所得税按如下公式计算:
1) 个人所得税起征点为3500元,若S不超过3500,则不交税,3500元以上的部分才计算个人所得税,令A=S-3500元;
2) A中不超过1500元的部分,税率3%;
3) A中超过1500元未超过4500元的部分,税率10%;
4) A中超过4500元未超过9000元的部分,税率20%;
5) A中超过9000元未超过35000元的部分,税率25%;
6) A中超过35000元未超过55000元的部分,税率30%;
7) A中超过55000元未超过80000元的部分,税率35%;
8) A中超过80000元的部分,税率45%;
例如,如果小明的税前工资为10000元,则A=10000-3500=6500元,其中不超过1500元部分应缴税1500×3%=45元,超过1500元不超过4500元部分应缴税(4500-1500)×10%=300元,超过4500元部分应缴税(6500-4500)×20%=400元。总共缴税745元,税后所得为9255元。
已知小明这个月税后所得为T元,请问他的税前工资S是多少元。
输入格式
输入的第一行包含一个整数T,表示小明的税后所得。所有评测数据保证小明的税前工资为一个整百的数。
输出格式
输出一个整数S,表示小明的税前工资。
样例输入
9255
样例输出
10000
评测用例规模与约定
对于所有评测用例,1 ≤ T ≤ 100000。
解题思路
- 税前工资S的不同税点区间是0 -> 3500 -> 3500+1500 -> 3500+4500-> 3500+9000 -> 3500+35000 -> 3500+55000 -> 3500+80000 -> 3500 + 80000 + … 。这些税点区间对应的税后工资区间是0 -> 3500 -> 4955 -> 7655 -> 11255 -> 30755 -> 44755 -> 61005 -> …。
- 对于税后工资T,根据T落在哪个税后区间内来计算税前工资S。以税后工资T在(7655, 11255]区间内为例,税前工资S = 3500 + 9000 + (T - 7655) / (1 - 0.25)。其中,3500 + 9000是税后工资7655对应的税前工资,(T - 7655) / (1 - 0.25)是超过9000未超过35000部分的税前工资。
参考答案
# 计算各个税率分界点的税前工资、税后工资和剩余比例(=1-税率)。
qian_hou_remain = []
qian = 3500
hou = 3500
qian_hou_remain.append((qian, hou, 1))
qian += 1500
hou += 1500 * (1 - 0.03)
qian_hou_remain.append((qian, hou, 1 - 0.03)) #qian是税前工资,hou是税后工资,1-0.03是剩余比例
qian += 3000
hou += 3000 * (1 - 0.1)
qian_hou_remain.append((qian, hou, 1 - 0.1))
qian += 4500
hou += 4500 * (1 - 0.2)
qian_hou_remain.append((qian, hou, 1 - 0.2))
qian += 35000 - 9000
hou += (35000 - 9000) * (1 - 0.25)
qian_hou_remain.append((qian, hou, 1 - 0.25))
qian += 55000 - 35000
hou += (55000 - 35000) * (1 - 0.3)
qian_hou_remain.append((qian, hou, 1 - 0.3))
qian += 80000 - 55000
hou += (80000 - 55000) * (1 - 0.35)
qian_hou_remain.append((qian, hou, 1 - 0.35))
# for qh in qian_hou_remain:
# print((qh[0] - 3500, qh[1], round(1 - qh[2], 2)), end=' ')
T = int(input())
if T <= 3500:
S = T
elif T >= qian_hou_remain[-1][1]: #超过80000的情形
S = qian_hou_remain[-1][0] + int(round((T - qian_hou_remain[-1][1]) / 0.55)) #!!!round()
else:
i = len(qian_hou_remain) - 1
while qian_hou_remain[i][1] > T: #计算T落在哪个区间
i -= 1
# print("i=", i)
S = qian_hou_remain[i][0] + int(round((T - qian_hou_remain[i][1]) / qian_hou_remain[i + 1][2]))
print(S)
测试用例
- 每个区间的起始和末尾都要构造对应的测试用例。这些测试用例的输入依次是:0, 3500 , 4955 , 7655, 11255 ,30755, 44755, 61005。请你自己计算这些输入各自对应的输出。
- 为每个区间的内部构造一个测试用例。这些测试用例的输入依次是:2000 , 3500+97 , 4955 +90, 7655 + 80, 11255 +75, 30755+70, 44755+65, 61005+55。请你自己计算这些输入各自对应的输出。
小结
- 这道题的求解是一个反向推导过程。
- 先得出各个税率分界点的税前工资与税后工资的映射关系,使得反向推导得到了简化。
- 上面的代码中,第24,25行输出税率分界点的税前工资、税后工资和剩余比例(=1-税率),目的是检验税率分界点的税前工资与税后工资是否正确。
- 测试用例的构造遵循了“边界值分析法”。讲软件测试的图书会介绍这种构造测试用例的方法。