1 条题解
-
0
题意分析
题目要求给出区域系数,税收系数和一个公民在某企业的净收入计算并输出总收入应纳税额与所有雇主预扣税之和的差额。
解题思路
净收入D = R+L%×R−T(R)−T(L%×R) 其中,R为税前收入,L为区域系数 总税前收=∑ 总应纳税额=T()+T(L%×) 预扣税之和=∑(T()+T(L%×)) 题目给出的是净收入,如果要从净收入直接计算税前收入会非常麻烦,因为税收是分段式的,可能需要计算每段税收的最大值和最小值,来确定净收入属于哪一个区间,但是这样依旧非常麻烦,因为每个数据的税收系数不一样,考虑到净收入是随着税前收入的增大而增大的,可以使用二分法求解,因此本题采用二分法求解税前收入,只要知道税前收入,那么问题都迎刃而解了,题目的数据可能会有差异,因此需要设置一个误差范围(本题为1e-7)。
标程
#include <iostream> #include <vector> #include <cmath> #include <iomanip> using namespace std; struct Tax { double salary; int rate; Tax(double salary = 0, int rate = 0) : salary(salary), rate(rate) {} }; double round2(double x) { return floor(x * 100 + 0.5) / 100; } double calculate_tax(double k, const vector<Tax>& segment){ double tax = 0.0; double prev_salary = 0.0; for(const auto& seg : segment){ double current_salary = seg.salary; int rate = seg.rate; if(k <= prev_salary){ continue; } double part = min(k,current_salary) - prev_salary; tax += part * rate / 100.0; prev_salary = current_salary; if(k <= current_salary){ break; } } return round2(tax); } double solveR(double D, double L, const vector<Tax>& segment){ double left = 0.0, right = D*2; for(int i = 1; i <= 100; i++){ double mid = (left + right) / 2; double sub = mid * L / 100.0; double tax_r = calculate_tax(mid,segment); double tax_sub = calculate_tax(sub,segment); double current_D = mid + sub - tax_r - tax_sub; if(current_D < D - 1e-8){ left = mid; } else{ right = mid; } } return round2((left + right)/2); } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int L; cin >> L; vector<Tax> segment; while(true){ double x; int y; cin >> x >> y; if(x == 0){ segment.push_back(Tax(1e18,y)); break; } segment.push_back(Tax(x,y)); } vector<double> Rs; double D; while(cin >> D && D != -1){ double R = solveR(D,L,segment); Rs.push_back(R); } double K_total = 0.0; for(double R : Rs){ K_total += R; } double sub_total = K_total * L / 100.0; double total_tax = calculate_tax(K_total,segment) + calculate_tax(sub_total,segment); double withheld_total = 0.0; for(double R : Rs){ double sub = R * L / 100.0; withheld_total += calculate_tax(R,segment) + calculate_tax(sub,segment); } double diff = total_tax - withheld_total; cout << fixed << setprecision(2) << round2(diff)<< endl; return 0; }
- 1
信息
- ID
- 1618
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 5
- 已通过
- 1
- 上传者